Snippets Collections
-- Determining what factors were more prevalent across all collisions
SELECT 
    COUNT(*) AS TOTAL_COLLISIONS,
    (SUM(CASE WHEN INATTENTIONIND = 1 THEN 1 ELSE 0 END) * 100.0 / COUNT(*)) AS PERC_INATTENTIONIND,
    (SUM(CASE WHEN UNDERINFL = 1 THEN 1 ELSE 0 END) * 100.0 / COUNT(*)) AS PERC_UNDERINFL,
    (SUM(CASE WHEN SPEEDING = 1 THEN 1 ELSE 0 END) * 100.0 / COUNT(*)) AS PERC_SPEEDING,
    (SUM(CASE WHEN HITPARKEDCAR = 1 THEN 1 ELSE 0 END) * 100.0 / COUNT(*)) AS PERC_HITPARKEDCAR,
    (SUM(CASE WHEN POORDRIVINGCOND = 1 THEN 1 ELSE 0 END) * 100.0 / COUNT(*)) AS PERC_POORDRIVINGCOND,
    (SUM(CASE WHEN NIGHTTIME = 1 THEN 1 ELSE 0 END) * 100.0 / COUNT(*)) AS PERC_NIGHTTIME,
    (SUM(CASE WHEN intersection_related = 1 THEN 1 ELSE 0 END) * 100.0 / COUNT(*)) AS PERC_INTERSECT_RELATED
FROM PortfolioProject.dbo.SeattleCollision;
-- Examining the number of collisions that ended in injuries vs fatalities
SELECT 
    COUNT(*) AS TOTAL_COLLISIONS,
    SUM(CASE WHEN FATALITIES > 0 THEN 1 ELSE 0 END) AS TOTAL_FATAL_COLLISIONS,
    (SUM(CASE WHEN FATALITIES > 0 THEN 1.0 ELSE 0 END) / COUNT(*)) * 100.0 AS PERCENTAGE_FATAL_COLLISIONS,
    SUM(CASE WHEN INJURIES > 0 THEN 1 ELSE 0 END) AS TOTAL_INJURIES,
    (SUM(CASE WHEN INJURIES > 0 THEN 1.0 ELSE 0 END) / COUNT(*)) * 100.0 AS PERCENTAGE_INJURIES
FROM 
    PortfolioProject.dbo.SeattleCollision;
-- Calculating the number of collisions per year and n of people affected
SELECT
    YEAR(DATE_UPD) AS COLLISION_YEAR,
    COUNT(*) AS COLLISIONS_PER_YEAR,
    SUM(PERSONCOUNT) AS TOTAL_AFFECTED
FROM PortfolioProject.dbo.SeattleCollision
GROUP BY YEAR(DATE_UPD)
ORDER BY COLLISIONS_PER_YEAR DESC;
-- Adding more descriptive labels to the Severity column
ALTER TABLE PortfolioProject.dbo.SeattleCollision
ADD SEVERITY nvarchar(255);
UPDATE PortfolioProject.dbo.SeattleCollision
SET SEVERITY = CASE 
		WHEN SEVERITYCODE = 3 THEN '3—fatality'
		WHEN SEVERITYCODE = 2 THEN '2—injury'
		WHEN SEVERITYCODE = 1 THEN '1—property damage'
		ELSE '0—unknown'
	END;
-- Creating a filter for Nighttime 
ALTER TABLE PortfolioProject.dbo.SeattleCollision
ADD NIGHTTIME bit;
UPDATE PortfolioProject.dbo.SeattleCollision
SET NIGHTTIME = CASE 
		WHEN TIMEOFDAY = 'Daylight' THEN 0
		ELSE 1
	END;
-- Creating a function for determining Daylight vs Nighttime
CREATE FUNCTION FINDTIMEOFDAY(
    @CollisionDate DATE,
    @CollisionTime TIME)
RETURNS VARCHAR(8)
AS
BEGIN
    DECLARE @MONTHN INT;
    DECLARE @SUNRISE TIME;
    DECLARE @SUNSET TIME;
    SELECT @MONTHN = MONTH(@CollisionDate);
    SELECT @SUNRISE = SUNRISE, @SUNSET = SUNSET
    FROM PortfolioProject.dbo.SeattleSunriseSunset
    WHERE MONTHN = @MONTHN;
    RETURN CASE 
        WHEN @CollisionTime >= @SUNRISE AND @CollisionTime < @SUNSET THEN 'Daylight'
        ELSE 'Night'
    END;
END;
-- Creating a filter for good vs poor driving conditions
ALTER TABLE PortfolioProject.dbo.SeattleCollision
ADD POORDRIVINGCOND bit;
UPDATE PortfolioProject.dbo.SeattleCollision
SET POORDRIVINGCOND = CASE 
		WHEN WEATHER = 'Clear' AND ROADCOND = 'Dry' THEN 0
		ELSE 1
	END;
-- Converting the values from the 'time' column into readable time formats
ALTER TABLE PortfolioProject.dbo.SeattleCollision
ADD N_TIME TIME;

UPDATE PortfolioProject.dbo.SeattleCollision
SET N_TIME = CAST(DATEADD(MINUTE, TIME * 60, '00:00') AS TIME);

ALTER TABLE PortfolioProject.dbo.SeattleCollision
ADD TIME_UPD NVARCHAR(255);

UPDATE PortfolioProject.dbo.SeattleCollision
SET TIME_UPD = CONVERT(NVARCHAR(255), N_TIME, 108);
-- Identifying the total number of collisions
SELECT count(*)
FROM PortfolioProject.dbo.SeattleCollision
-- Ordering the columns, filtering out low rating counts and missing isbn rows and non-sci-fi books
SELECT id, isbn, rating_100, rating_count, numberofreviews, title, author, publishing_year, genre_science_fiction
FROM PortfolioProject.dbo.Goodreads
WHERE genre_science_fiction ='Yes' AND rating_count > 30 AND isbn IS NOT NULL
ORDER BY rating DESC
UPDATE PortfolioProject.dbo.Goodreads
SET genre_fantasy = CASE WHEN genres LIKE '%fantasy%' THEN 'Yes' ELSE 'No' END,
    genre_romance = CASE WHEN genres LIKE '%romance%' THEN 'Yes' ELSE 'No' END,
    genre_young_adult = CASE WHEN genres LIKE '%young adult%' THEN 'Yes' ELSE 'No' END,
    genre_paranormal = CASE WHEN genres LIKE '%paranormal%' THEN 'Yes' ELSE 'No' END,
    genre_classics = CASE WHEN genres LIKE '%classics%' THEN 'Yes' ELSE 'No' END,
    genre_science_fiction = CASE WHEN genres LIKE '%science fiction%' THEN 'Yes' ELSE 'No' END,
    genre_mystery = CASE WHEN genres LIKE '%mystery%' THEN 'Yes' ELSE 'No' END,
    genre_childrens = CASE WHEN genres LIKE '%childrens%' THEN 'Yes' ELSE 'No' END,
    genre_adventure = CASE WHEN genres LIKE '%adventure%' THEN 'Yes' ELSE 'No' END;
-- Creating filter columns based on the genre hits
ALTER TABLE PortfolioProject.dbo.Goodreads
ADD genre_fantasy NVARCHAR(255),
    genre_romance NVARCHAR(255),
    genre_young_adult NVARCHAR(255),
    genre_paranormal NVARCHAR(255),
    genre_classics NVARCHAR(255),
    genre_science_fiction NVARCHAR(255),
    genre_mystery NVARCHAR(255),
    genre_childrens NVARCHAR(255),
    genre_adventure NVARCHAR(255);
-- Exploring the most popular tags in the genres column
SELECT TOP 100
	value [word],
	COUNT(*) [#times]
FROM  PortfolioProject.dbo.Goodreads
CROSS APPLY STRING_SPLIT(Goodreads.genres, '|') 
GROUP BY value
ORDER BY COUNT(*) DESC
-- Cleaning up the Genres column
UPDATE PortfolioProject.dbo.Goodreads
SET genres = REPLACE(REPLACE(REPLACE(genres, '/genres/', ''), '-', ' '), '|', ' | ');
-- Splitting out the authors column based on the author_url column
ALTER TABLE PortfolioProject.dbo.Goodreads
ADD author NVARCHAR(255);

UPDATE PortfolioProject.dbo.Goodreads
SET author = REPLACE(PARSENAME(REPLACE(author_url, ',', '.'), 1), '_', ' ');
-- Removing duplicate rows
DELETE FROM PortfolioProject.dbo.Goodreads
WHERE isbn = '0439023483'
AND id <> (SELECT MIN(id)
           FROM PortfolioProject.dbo.Goodreads
           WHERE isbn = '0439023483');
-- Identifying duplicate values
SELECT isbn, COUNT(*)
FROM PortfolioProject.dbo.Goodreads
GROUP BY isbn
HAVING COUNT(*) > 1;

SELECT *
FROM PortfolioProject.dbo.Goodreads
WHERE isbn = '0439023483';
-- Standardising the ratings column 
ALTER TABLE PortfolioProject.dbo.Goodreads
ADD rating_100 float;
UPDATE PortfolioProject.dbo.Goodreads
SET rating_100 = rating * 20
-- Updating the missing values to read as NULL
UPDATE PortfolioProject.dbo.Goodreads SET isbn = NULL WHERE isbn ='None';
UPDATE PortfolioProject.dbo.Goodreads SET media_type = NULL WHERE media_type ='None';
UPDATE PortfolioProject.dbo.Goodreads SET author_url = NULL WHERE author_url ='None';
UPDATE PortfolioProject.dbo.Goodreads SET title = NULL WHERE title='None';
UPDATE PortfolioProject.dbo.Goodreads SET genres = NULL WHERE genres='None';

-- Clearing the rows where most of the data is missing
DELETE FROM PortfolioProject.dbo.Goodreads WHERE media_type is null
-- Examining the table for null values
SELECT COUNT(*)-COUNT(rating) AS rating
	 , COUNT(*)-COUNT(numberofreviews) AS n_of_reviews
	 , COUNT(*)-COUNT(isbn) AS isbn
	 , COUNT(*)-COUNT(publishing_year) AS publishing_year
	 , COUNT(*)-COUNT(genres) AS genres
	 , COUNT(*)-COUNT(rating_count) AS rating_count
	 , COUNT(*)-COUNT(title) AS title
FROM PortfolioProject.dbo.Goodreads;
-- Renaming the columns 
EXEC sp_rename 'Goodreads.4#4', 'rating';
EXEC sp_rename 'Goodreads.136455', 'numberofreviews';
EXEC sp_rename 'Goodreads.0439023483', 'isbn';
EXEC sp_rename 'Goodreads.good_reads:book', 'media_type';
EXEC sp_rename 'Goodreads.https://www#goodreads#com/author/show/153394#Suzanne_Collins', 'author_url';
EXEC sp_rename 'Goodreads.2008', 'publishing_year';
EXEC sp_rename 'Goodreads./genres/young-adult|/genres/science-fiction|/genres/dystopia|/ge', 'genres';
EXEC sp_rename 'Goodreads.dir01/2767052-the-hunger-games#html', 'directory';
EXEC sp_rename 'Goodreads.2958974', 'rating_count';
EXEC sp_rename 'Goodreads.The Hunger Games (The Hunger Games, #1)', 'title';
-- Duplicating the first row of data before renaming the columns
INSERT INTO PortfolioProject.dbo.Goodreads
VALUES (
	4.4
	, 136455
	, '0439023483'
	, 'good_reads:book'
	, 'https://www.goodreads.com/author/show/153394.Suzanne_Collins'
	, 2008
	, '/genres/young-adult|/genres/science-fiction|/genres/dystopia|/genres/fantasy|/genres/science-fiction|/genres/romance|/genres/adventure|/genres/book-club|/genres/young-adult|/genres/teen|/genres/apocalyptic|/genres/post-apocalyptic|/genres/action'
	, 'dir01/2767052-the-hunger-games.html'
	, 2958974
	, 'The Hunger Games (The Hunger Games, #1)'
	)
-- Adding an ID column to improve table navigation
ALTER TABLE PortfolioProject.dbo.Goodreads
ADD id INT IDENTITY(1,1);
-- Adding an ID column to improve table navigation
ALTER TABLE PortfolioProject.dbo.Goodreads
ADD id INT IDENTITY(1,1);
const model = this.data.model,
    records = this.data.selectedRecords;
let values = records.map( r => model.getValue( r, "JCLASS_DISPLAY" ) ); 

apex.item( "P230_CURRENT_JNYID" ).setValue( values[0] );
void assignPermissions(String srcDir,String fileName,Session session){
        String command = "sudo chmod 777 " + srcDir + "/" + fileName;

        try {
            ChannelExec channelExec = (ChannelExec) session.openChannel("exec");
            channelExec.setCommand(command);

            InputStream in = channelExec.getInputStream();

            // Connect to the channel
            channelExec.connect();

            // Read the output of the command (if any)
            BufferedReader reader = new BufferedReader(new InputStreamReader(in));
            String line;
            while ((line = reader.readLine()) != null) {
                System.out.println(line);
            }
            reader.close();

            // Wait for the command to finish
            while (!channelExec.isClosed()) {
                Thread.sleep(1000);
            }

            // Check the exit status of the command
            int exitStatus = channelExec.getExitStatus();
            if (exitStatus != 0) {
                // Handle error
                System.out.println("Error executing command. Exit status: " + exitStatus);
            } else {
                System.out.println("Command executed successfully.");
            }

            // Disconnect the channel
            channelExec.disconnect();
        } catch (Exception e) {
            // Handle exception
            e.printStackTrace();
        }
    }
= Sql.Database("USORASPSQLINT", "CLARINS_AUDIT",
               [Query="SELECT #(lf)    TASKDETAILKEY,#(lf)    TASKTYPE,#(lf)    DESCRIPTION,#(lf)    STORERKEY,#(lf)    SKU,#(lf)    UOM,#(lf)    UOMQTY,#(lf)    FROMLOC,#(lf)    FROMID,#(lf)    TOLOC,#(lf)    TOID,#(lf)    ORDERKEY,#(lf)    ORDERLINENUMBER,#(lf)    WAVEKEY,#(lf)    PRIORITY,#(lf)    STATUS,#(lf)    ROUTE,#(lf)    CONVERT(DATE, ADDDATE) AS ADDDATE,#(lf)    ADDWHO,#(lf)    CONVERT(DATE, EDITDATE) AS EDITDATE,#(lf)    EDITWHO,#(lf)    STARTTIME,#(lf)    CONVERT(DATE, ENDTIME) AS ENDTIME#(lf)
               FROM CLARINS_AUDIT.SCE.vw_TASKDETAIL_Pending;#(lf)"])
                
package com.modeln.channelcollab.junit;

import com.modeln.channelnetwork.junit.graphql.AbstractChannelNetworkTest;
import com.modeln.channelnetwork.junit.graphql.GraphQLClient;
import com.modeln.channelnetwork.junit.graphql.SubmissionScheduleClient;
import io.restassured.path.json.JsonPath;
import io.restassured.response.Response;
import org.junit.Assert;
import org.junit.jupiter.api.*;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.test.context.junit.jupiter.SpringExtension;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;

@ExtendWith(SpringExtension.class)
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
@Tag("graphql")
public class SubmissionResultsTest extends AbstractChannelNetworkTest
{
    public static final String SUBMISSION_SCHEDULE_FILE_NAME_PREFIX = "Submission_Schedule_";
    public static String newSubmissionSchedulefilename, invoiceDate;

    public static final Integer DEFAULT_OFFSET = 0, DEFAULT_LIMIT = 100;

    public static SubmissionScheduleClient adminClient;

    public static BigDecimal sid;

    @Autowired
    protected JdbcTemplate jdbcTemplate;

    public static final String SUBMISSION_SCHEDULE_QUERY_OUTPUT_JSON = "SELECT distinct JSON_OBJECT('sid' value ss.sid,'reporting_partner_name' value rp_ovw.entity_name,'name' value name,'periodRule' value period_rule,'dataType' value dt.type ,'expectedDay' value expected_day,'isInPeriodReporter' value case when is_in_period_reporter = '1' then 'true' Else 'false' end,'weekOfMonth' value week_of_month,'monthOfQuarter' value month_of_quarter,'startDate' value start_date,'endDate' value end_date) AS \" \" FROM submission_schedule ss join reporting_partner rp on rp.sid = ss.reporting_partner_sid left join data_type dt on dt.sid = ss.data_type_sid left join rp_csr_overlay_v rp_ovw on rp_ovw.ip_sid = rp.inow_profile_sid";

    public static String NO_DATA_REASON = "SYSTEM ISSUE", noDataReason;

    public static String GET_SID_TO_UPDATE = "select sid from submission_period";

    public static final String ACQUIRE_LOCK_GRAPHQL_MUTATION = "mutation acquireLock{" +
            "  acquireLock(objectType: SUBMISSION_PERIOD, sid: $sid) {" +
            "    userId" +
            "    serviceName" +
            "    sid" +
            "    expiration" +
            "  }" +
            "}";

    public static String MARK_NO_DATA_MUTATION = "mutation markNoData{" +
            "  markNoData(data: [{" +
            "        sid: $sid, " +
            "    noDataReason: \"$noDataReason\"" +
            "  }]) {" +
            "    sid "+
            "    status" +
            "    code" +
            "    message" +
            "  }" +
            "}";

    public static final String CHECK_NO_DATA_FOR_SID = "select no_data from submission_period where sid = :sid";

    public static final String CHECK_NO_DATA_REASON_FOR_SID = "select no_data_reason from submission_period where sid = :sid";

    @BeforeAll
    public void createClient() throws Exception
    {
        String endPoint = getEnvironment().getProperty(
                GraphQLClient.CHANNEL_NETWORK_GRAPHQL_URI);
        adminClient = new SubmissionScheduleClient(endPoint, generateUser1Token());
        List fromDb = jdbcTemplate.queryForList(SUBMISSION_SCHEDULE_QUERY_OUTPUT_JSON);
        if (fromDb.size() == 0)
        {
            uploadFileToCreateNewSubmissionSchedule();
        }
    }

    public void uploadFileToCreateNewSubmissionSchedule() throws Exception
    {
        newSubmissionSchedulefilename = getFilename(SUBMISSION_SCHEDULE_FILE_NAME_PREFIX, XLS_EXTENSION);
        LocalDate localDate = LocalDate.now();
        invoiceDate = DateTimeFormatter.ofPattern("MM/dd/yy").format(localDate.plusMonths(1).withDayOfMonth(1));
        String date2 = DateTimeFormatter.ofPattern("MM/dd/yy").format(localDate.withDayOfMonth(1));

        String[] rowData1 =
                { "CTHULHU", "Y", "\"ARROW PARTNER Transaction WEEKLY 20000000\"", "", "WEEKLY",
                        "Monday", "ARROW", "transaction", "No",
                        date2, "",
                        "ci_testuserint_email@cdmutlmail.aws.modeln.com", "Y", "", "Y",
                        "Y", "", "" };

        String[] rowData2 =
                { "CTHULHU", "Y", "\"CC SS BASE PARTNER Inventory MONTHLY 20000000\"", "", "MONTHLY",
                        "1", "BASE", "inventory", "Yes",
                        date2, "",
                        "ci_testuserint_email@cdmutlmail.aws.modeln.com", "Y", "", "Y",
                        "Y", "", "" };

        String[] rowData3 =
                { "CTHULHU", "Y", "\"AMSDIRSAP PARTNER Inventory DAILY 20000000\"", "", "QUARTERLY",
                        "1", "AMSDIRSAP", "inventory", "No",
                        date2, "",
                        "ci_testuserint_email@cdmutlmail.aws.modeln.com", "Y", "", "Y",
                        "Y", "", "1" };

        String[] rowData4 =
                { "CTHULHU", "Y", "\"BASE PARTNER 2 Transaction MONTHLY 20000000\"", "", "MONTHLY",
                        "1", "BASE2", "transaction", "No",
                        date2, "",
                        "ci_testuserint_email@cdmutlmail.aws.modeln.com", "Y", "", "Y",
                        "Y", "", "1" };

        String[][] fileData = new String[][]
                { CTH_SUBMISSION_SCHEDULE_FIELDS, rowData1, rowData2, rowData3, rowData4 };

        createXlsFile(getEnvironment(), fileData,
                newSubmissionSchedulefilename);
        invokeFileScanner(CLIENT_ID);
        waitForFileUploadSuccess(newSubmissionSchedulefilename);
        Thread.sleep(10000);
    }

    @Test
    public void submissionResultsTest() throws Exception
    {
        List<Map<String, Object>> sidList = jdbcTemplate.queryForList(GET_SID_TO_UPDATE);
        Map<String, Object> params = new HashMap<String, Object>();
        for(int i=0;i<sidList.size();i++)
        {
            sid = (BigDecimal) sidList.get(i).get("SID");
            params.put("sid", sid);
            String noDataForSid = getNamedParamJdbcTemplate()
                    .queryForObject(CHECK_NO_DATA_FOR_SID, params, String.class);
            Map<String, Object> mutationVariables = new HashMap<>();
            mutationVariables.put("sid", sid);
            mutationVariables.put("noDataReason", NO_DATA_REASON);
            String acquireLockMutation = ACQUIRE_LOCK_GRAPHQL_MUTATION.replace("$sid", sid.toString());

            Response response = adminClient.submissionScheduleQueryrunner(DEFAULT_LIMIT,
                    DEFAULT_OFFSET, null, null,
                    acquireLockMutation);
            noDataReason = getNamedParamJdbcTemplate()
                    .queryForObject(CHECK_NO_DATA_REASON_FOR_SID, params, String.class);

            if (Integer.parseInt(noDataForSid) == 0)
            {
                String markNoDataMutation = MARK_NO_DATA_MUTATION.replace("$sid", sid.toString()).replace("$noDataReason", NO_DATA_REASON);

            adminClient.submissionScheduleQueryrunner(DEFAULT_LIMIT,
                    DEFAULT_OFFSET, null, null,
                        markNoDataMutation);

            Thread.sleep(1000);
        }

        else {

            String markNoDataMutation = MARK_NO_DATA_MUTATION.replace("$sid", sid.toString()).replace("$noDataReason", NO_DATA_REASON);

            Response response1 = adminClient.submissionScheduleQueryrunner(DEFAULT_LIMIT,
                    DEFAULT_OFFSET, null, null,
                        markNoDataMutation);

            String message = JsonPath.with(response1.getBody().asString())
                    .get("data.markNoData[0].message");

            Assert.assertEquals(message,"Submission Period already has reported data, so No-Data-To-Report is not applicable.");
        }

            noDataForSid = getNamedParamJdbcTemplate()
                    .queryForObject(CHECK_NO_DATA_FOR_SID, params, String.class);
        Assert.assertEquals(Integer.parseInt(noDataForSid), 1);
        noDataReason = getNamedParamJdbcTemplate()
                    .queryForObject(CHECK_NO_DATA_REASON_FOR_SID, params, String.class);
        Assert.assertEquals(noDataReason, NO_DATA_REASON);
    }
    }
}
WITH cte AS (
    SELECT *, ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) rn
    FROM (SELECT attribute AS attr1, value AS val1 FROM temp WHERE attribute = 'height') t1
    CROSS JOIN (SELECT attribute AS attr2, value AS val2 FROM temp WHERE attribute = 'weight') t2
    CROSS JOIN (SELECT attribute AS attr3, value AS val3 FROM temp WHERE attribute = 'gender') t3
)

SELECT rn AS Combination, attr1 AS Attribute, val1 AS Value FROM cte WHERE attr1 = 'height' UNION ALL
SELECT rn, attr2, val2 FROM cte WHERE attr2 = 'weight' UNION ALL
SELECT rn, attr3, val3 FROM cte WHERE attr3 = 'gender'
ORDER BY Combination, Attribute, Value;
SELECT
   CCY1, CCY2, CER.Exchange_Rate
FROM
    ( 
    SELECT
        c1.rec_id AS rec_id1, c1.currency AS CCY1,
        c2.rec_id AS rec_id2, c2.currency AS CCY2
    FROM
        currency c1
        CROSS JOIN --all combinations...
        currency c2
    WHERE
        c1.rec_id <> c2rec_id -- ...removes same pairs
    ) foo
    LEFT JOIN -- ...get matching FX pairs
    CurrencyExchangeRate CER ON foo.rec_id1 = cer.[from] AND foo.rec_id2 = cer.[to]
SELECT 
  c1.currency AS [From], c2.currency AS [To] , cer.Exchange_Rate
FROM
  currency c1 JOIN currency c2 ON c1.rec_id <> c2.rec_id
  LEFT OUTER JOIN CurrencyExchangeRate cer ON c1.rec_id = cer.[from] 
         AND c2.rec_id = cer.[to]
LOAD DATA INFILE '{  [file_path]  /  [file_name].csv}'
INTO TABLE table_name
FIELDS TERMINATED BY ','
ENCLOSED BY '"'
LINES TERMINATED BY '\n'
IGNORE 1 ROWS;
dateadd(DAY,0, datediff(day,0, created)) will return the day created

for example, if the sale created on '2009-11-02 06:12:55.000', dateadd(DAY,0, datediff(day,0, created)) return '2009-11-02 00:00:00.000'

select sum(amount) as total, dateadd(DAY,0, datediff(day,0, created)) as created
from sales
group by dateadd(DAY,0, datediff(day,0, created))
query SubmissionPeriod {
  submissionPeriods(
    limit: 10
    offset: 0
    sort: {
      numberOfFiles:{
        order:1,
        direction:ASC
      }
    }
    filters: {
    status:{
      operator:EQUAL,
      value:"On-time"
    },
      submissionSchedule:{
        reportingPartner:{
          partnerOverlayView:{
            name:{
              operator:CONTAINS,
              value:"%WAV RISE%"
            }
          }
        }
      }
      
      
    }
  ) {
    sid
    createDate
    updateDate
    customerSid
    expectedDay
    expectedDate
    isInPeriodReporter
    noData
    noDataCreateDate
    noDataReason
    onTimeOverride
    periodEndDate
    periodStartDate
    reportedFlag
    status
    trackingLevel
    workingDays
    numberOfFiles
    dataFileSummaryInfo {
      numberOfPOSLines
      numberOfInventoryLines
      receivedDate
      dataFile {
        id
        createDate
        fileName
        dataType
        __typename
      }
      __typename
    }
    noDataServiceUser {
      sid
      firstName
      lastName
      email
      __typename
    }
    submissionPeriodLineItemView {
      salesLineItemCount
      invLineItemCount
      earliestFileSubmissionDate
      __typename
    }
    submissionSchedule {
      sid
      name
      periodRule
      dataType {
        type
        __typename
      }
      reportingPartner {
        id
        partnerOverlayView {
          name
          street1
          street2
          city
          stateprovince
          postalcode
          country
          __typename
        }
        __typename
      }
      __typename
    }
    __typename
  }
}
(select
      count(df.id) as number_of_files
      from SUBMISSION_SCHEDULE ss1
      left join DATA_FILE_SUMMARY_INFO dfsi on 
                                       dfsi.SUBMISSION_PERIOD_SID =  :sid
                                       AND dfsi.CUSTOMER_SID = :cs
      left join DATA_TYPE dt1 on ss1.DATA_TYPE_SID = dt1.SID
      left join DATA_FILE df on dfsi.CUSTOMER_SID = df.CUSTOMER_SID
                          AND dfsi.DATA_FILE_SID = df.SID
                          AND df.DELETED = 0
                          --AND df.DATA_TYPE = dt1.TYPE
      where ss1.SID = :spssd
      AND ss1.CUSTOMER_SID= :cs);
SELECT 
  content.title,
  content.body,
  content.published,
  author.url,
FROM 
  `3000_forum_boards___updated_daily___english.socialgist_boards_english_public`
  -- Make sure these parameters match the names you set for the dataset and tables
WHERE 
  content.published BETWEEN '2023-01-01' AND '2024-02-29'
  AND (content.body LIKE '%Super Bowl%' OR content.title LIKE '%Super Bowl%')
LIMIT 10;
SELECT
  content.title,
  content.body,
  content.published,
  author.url
FROM
  `200_boards___updated_daily___chinese.socialgist_boards_chinese_public`
-- Make sure the dataset and table selectors use the same name you set when you linked the dataset.
WHERE
  LOWER(content.body) LIKE '%经济%' 
-- The keyword is the word 'economy' in Chinese characters. You can change this to any keyword you wish to scan for in the content body. 
ORDER BY
  content.published DESC
LIMIT 10 -- Limits the results to 100 for demonstration purposes.
CREATE OR REPLACE TEMPORARY TABLE TBL_NUMBER
(
	NUM FLOAT
)
AS
SELECT
	*
FROM
	VALUES(2),(3),(4);

SELECT
    EXP
    (
      SUM
      (
        LN(NUM)
      )
    ) AS RESULT
FROM
	TBL_NUMBER
SELECT DISTINCT  V1.SKU AS SKU, V2.DESCR AS ItemName, SUM(V1.SHIPPEDQTY) 
FROM SCE.vw_ORDERDETAIL_1 V1
INNER JOIN SCE.vw_SKU V2 ON V1.SKU = V2.SKU 
WHERE V1.ACTUALSHIPDATE BETWEEN '2024-01-01 00:00:00' AND GETDATE()
GROUP BY v1.SKU, V2.DESCR
HAVING SUM(V1.SHIPPEDQTY) > 0
DECLARE @pattern varchar(52) = '0123456789 abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
SELECT 
   v.[Text], 
   REPLACE(
      TRANSLATE(
         v.[Text],
         REPLACE(TRANSLATE(v.[Text], @pattern, REPLICATE('a', LEN(@pattern))), 'a', ''),
		 REPLICATE('~', LEN(REPLACE(REPLACE(TRANSLATE(v.[Text], @pattern, REPLICATE('a', LEN(@pattern))), 'a', ''), ' ', '.')))
      ),
      '~',
      ''
   ) AS AlphaNumericCharacters
FROM (VALUES
   ('abc01234def5678ghi90jkl#@$&"'),
   ('1234567890'),
   ('JAHDBESBN%*#*@*($E*sd55bn')
) v ([Text]);
[image]=cast(Replace([image],'data:image/jpeg;base64,','')as xml).value('xs:base64Binary(.)', 'varbinary(max)')
function(config) { 
   config.defaultGridViewOptions = { 
      footer: false } 
return config; } 
        
  WITH NUMBEROFTOTALORDER AS (
  
	SELECT DISTINCT Count(*) As NumberofTotalOrder
	From [SCE].[vw_ORDERS_1] 
	WHERE vw_ORDERS_1.TYPE IN ('ECOM','ECOMAPP')
	AND vw_ORDERS_1.STATUS NOT IN (95,98,99) 
	/* 95 = Shipped Complete, 98 = Cancelled Externally, 99 = Canceled Internally */ 
	
  ), PICKED AS (
  
    SELECT DISTINCT Count(*) As Picked
	From [SCE].[vw_ORDERS_1] 
	WHERE vw_ORDERS_1.TYPE IN ('ECOM','ECOMAPP')
	AND vw_ORDERS_1.STATUS IN (55) 
	
	/* 15 =  Part Allocated / Part Picked
	 * 25 = Part Released/Part Picked
	 * 51 = In Picking
	 * 52 = Part Picked
	 * 53 = Part Picked / Part Shipped
	 * 55 = Picked Complete
	 * 57 = Picked / Part Shipped
	 *  */ 
  
  ), PACKED AS (
  
	SELECT DISTINCT Count(*) As Packed
	From [SCE].[vw_ORDERS_1] 
	WHERE vw_ORDERS_1.TYPE IN ('ECOM','ECOMAPP')
	AND vw_ORDERS_1.STATUS IN (68) 
	
	/* 61 =  In Packing
	 * 68 = Pack Complete
	 *  */
	
	), PRIORITY AS (
	
	SELECT DISTINCT Count(*) As Priority
	From [SCE].[vw_ORDERS_1] 
	WHERE vw_ORDERS_1.TYPE IN ('ECOM','ECOMAPP')
	AND vw_ORDERS_1.STATUS NOT IN (95,98,99) 
	AND vw_ORDERS_1.PRIORITY IN (1,2,3)
	
	/* 95 = Shipped Complete, 98 = Cancelled Externally, 99 = Canceled Internally */ 
	/* 1 = Highest Priority, 3 = Normal Priority */
 
    ), ACTUALORDER AS (
    
    SELECT DISTINCT Count(*) As ActualOrder
	From [SCE].[vw_ORDERS_1] 
	WHERE vw_ORDERS_1.TYPE in ('ECOM','ECOMAPP')
	AND vw_ORDERS_1.ORDERDATE = DATEADD(dd, -1, CAST( GETDATE() AS Date)) 

	), ORDERSHIPPED24HOUROLD AS (
	
	SELECT OrderShipped24HourOld, 
	CASE 
		WHEN DATENAME(weekday, GETDATE()) = 'Monday' THEN 
		(
			SELECT DISTINCT COUNT(*) As OrderShipped24HourOld
			From [SCE].[vw_ORDERS_1] 
			WHERE vw_ORDERS_1.TYPE IN ('ECOM','ECOMAPP')
			AND vw_ORDERS_1.ACTUALSHIPDATE=  DATEADD(dd,-3,CAST( GETDATE() AS Date))
			AND vw_ORDERS_1.ORDERDATE = DATEADD(dd,-4,CAST( GETDATE() AS Date ))
		
		)
		
		
	
	
	
	), ORDERSHIPPEDGREATERTHAN24HOUROLD AS 
	
		IF (DATENAME(weekday, GETDATE()) IN ('Monday'))
			BEGIN
				SELECT DISTINCT Count(*) As OrdersShippedGreaterThan24HoursOldForMONDAY
				FROM [SCE].[vw_ORDERS_1] 
				WHERE vw_ORDERS_1.TYPE IN ('ECOM','ECOMAPP')
				AND vw_ORDERS_1.ACTUALSHIPDATE = DATEADD(dd,-3,CAST( GETDATE() AS Date ))
				AND vw_ORDERS_1.ORDERDATE < DATEADD(dd,-4,CAST( GETDATE() AS Date ))
			END
		ELSE IF (DATENAME(weekday, GETDATE()) IN ('Tuesday'))
			BEGIN
				SELECT DISTINCT Count(*) As OrdersShippedGreaterThan24HoursOldForTuesday
				FROM [SCE].[vw_ORDERS_1] 
				WHERE vw_ORDERS_1.TYPE IN ('ECOM','ECOMAPP')
				AND vw_ORDERS_1.ACTUALSHIPDATE = DATEADD(dd,-1,CAST( GETDATE() AS Date ))
				AND vw_ORDERS_1.ORDERDATE < DATEADD(dd,-4,CAST( GETDATE() AS Date ))
			END
		ELSE
			BEGIN
				SELECT DISTINCT Count(*) As OrderShippedGreaterThan24HourOld
				FROM [SCE].[vw_ORDERS_1] 
				WHERE vw_ORDERS_1.TYPE IN ('ECOM','ECOMAPP')
				AND vw_ORDERS_1.ACTUALSHIPDATE = DATEADD(dd,-1,CAST( GETDATE() AS Date ))
				AND vw_ORDERS_1.ORDERDATE < DATEADD(dd,-2,CAST( GETDATE() AS Date ))
			END
	)
  	SELECT NUMBEROFTOTALORDER.NumberofTotalOrder, PICKED.Picked, PACKED.Packed, PRIORITY.Priority, ACTUALORDER.ActualOrder, ORDERSHIPPED24HOUROLD.OrderShipped24HourOld,
  	ORDERSHIPPEDGREATERTHAN24HOUROLD.OrderShippedGreaterThan24HourOld
	FROM DAYSTART, PICKED, PACKED, PRIORITY, ACTUALORDER, ORDERSHIPPED24HOUROLD, ORDERSHIPPEDGREATERTHAN24HOUROLD
	

IF (DATENAME(weekday, GETDATE()) = 'Monday')
		BEGIN
			SELECT DISTINCT COUNT(*) As OrderShipped24HourOld
			From [SCE].[vw_ORDERS_1] 
			WHERE vw_ORDERS_1.TYPE IN ('ECOM','ECOMAPP')
			AND vw_ORDERS_1.ACTUALSHIPDATE=  DATEADD(dd,-3,CAST( GETDATE() AS Date))
			AND vw_ORDERS_1.ORDERDATE = DATEADD(dd,-4,CAST( GETDATE() AS Date ))	
		END
	ELSE IF (DATENAME(weekday, GETDATE()) = 'Tuesday')
		BEGIN
			SELECT DISTINCT Count(*) As OrderShipped24HourOld
			From [SCE].[vw_ORDERS_1] 
			WHERE vw_ORDERS_1.TYPE IN ('ECOM','ECOMAPP')
			AND vw_ORDERS_1.ACTUALSHIPDATE=  DATEADD(dd,-1,CAST( GETDATE() AS Date ))
			AND vw_ORDERS_1.ORDERDATE = DATEADD(dd,-4,CAST( GETDATE() AS Date ))
		END
	ELSE
		BEGIN
			SELECT DISTINCT Count(*) As OrderShipped24HourOld
			From [SCE].[vw_ORDERS_1] 
			WHERE vw_ORDERS_1.TYPE IN ('ECOM','ECOMAPP')
			AND vw_ORDERS_1.ACTUALSHIPDATE = DATEADD(dd,-1,CAST( GETDATE() AS Date ))
			AND vw_ORDERS_1.ORDERDATE = DATEADD(dd,-2,CAST( GETDATE() AS Date ))	
		END	 
	
	
	
	

// Go through the stack overflow code to determine the best solution
Check Link

https://learn.microsoft.com/en-us/sql/t-sql/language-elements/while-transact-sql?view=sql-server-ver16

https://learn.microsoft.com/en-us/sql/t-sql/language-elements/if-else-transact-sql?view=sql-server-ver16


Instead of reading the table twice, we only need to read it once and can return one set of results. This query also has the same 30046 logical reads.

PIVOT 

Learn how to use Pivot to do this
WITH cte1 AS(
 SELECT COUNT(*) cnt 
 FROM table1
 WHERE....
), cte2 AS(
 SELECT COUNT(*) cnt
 FROM table1
 WHERE....
), cte3 AS(
 SELECT COUNT(*) cnt
 FROM table 1
 WHERE....
)
SELECT cte1.cnt AS cte1, cte2.cnt AS cte2, cte3.cnt AS cte3
FROM cte1, cte2, cte3

SELECT
  (SELECT COUNT(*) FROM table1 WHERE....) as cte1,
  (SELECT COUNT(*) FROM table1 WHERE....) as cte2,
  (SELECT COUNT(*) FROM table1 WHERE....) as cte3
version: "1.0"

name: ChannelNetwork

# All actions

actions:
  - name: VIEW
  - name: UPDATE

# All resources

resources:
  # UI Resource for access to kpis tab
  - name: ProductKpiTab
    actions: [VIEW]

    ### Begin productKpi fields

  - name: ProductKpi
    group: productKpi
    actions: [VIEW]

  - name: ProductKpi/*
    group: productKpi
    actions: [VIEW]

    ### End productKpi fields

    ### Begin salesKpi fields

  - name: SalesKpi
    group: salesKpi
    actions: [VIEW]

  - name: SalesKpi/*
    group: salesKpi
    actions: [VIEW]

    ### End salesKpi fields

    ### Begin inventoryKpi fields

  - name: InventoryKpi
    group: inventoryKpi
    actions: [VIEW]

  - name: InventoryKpi/*
    group: inventoryKpi
    actions: [VIEW]

    ### End inventoryKpi fields

    ### Begin filesKpi fields

  - name: FilesKpi
    group: filesKpi
    actions: [VIEW]

  - name: FilesKpi/*
    group: filesKpi
    actions: [VIEW]

    ### End filesKpi fields

    ### Begin ssKpi fields

  - name: SSKpi
    group: ssKpi
    actions: [VIEW]

  - name: SSKpi/*
    group: ssKpi
    actions: [VIEW]

    ### End ssKpi fields


    # UI Resource for access to Products tab
  - name: ProductTab
    actions: [VIEW, UPDATE]

    ### Begin Product Fields

  - name: Product
    group: product
    actions: [VIEW, UPDATE]

  - name: Product/sid
    group: product
    actions: [VIEW]

  - name: Product/createDate
    group: product
    actions: [VIEW]

  - name: Product/updateDate
    group: product
    actions: [VIEW]

  - name: Product/customerSid
    group: product-internal
    actions: [VIEW]

  - name: Product/sku
    group: product
    actions: [VIEW]

  - name: Product/name
    group: product
    actions: [VIEW]

  - name: Product/description
    group: product
    actions: [VIEW]

  - name: Product/productFamily
    group: product
    actions: [VIEW]

  - name: Product/productLine
    group: product
    actions: [VIEW]

  - name: Product/startDate
    group: product
    actions: [VIEW]

  - name: Product/endDate
    group: product
    actions: [VIEW]

  - name: Product/serialized
    group: product-internal
    actions: [VIEW]

  - name: Product/aggregation
    group: product-pos-aggr
    actions: [VIEW]

  - name: Product/aggregation/totalSalesLineCount
    group: product-pos-aggr
    actions: [VIEW]

  - name: Product/aggregation/totalSalesQuantity
    group: product-pos-aggr
    actions: [VIEW]

  - name: Product/aggregation/oldestInvoiceDate
    group: product-pos-aggr
    actions: [VIEW]

    ## Begin Product Dynamic Attrs


  - name: Product/dynamicAttrs
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/sid
    group: product-dynamicAttrs-internal
    actions: [VIEW]
  - name: Product/dynamicAttrs/updateDate
    group: product-dynamicAttrs-internal
    actions: [VIEW]
  - name: Product/dynamicAttrs/createDate
    group: product-dynamicAttrs-internal
    actions: [VIEW]
  - name: Product/dynamicAttrs/attributeType
    group: product-dynamicAttrs-internal
    actions: [VIEW]
  - name: Product/dynamicAttrs/STRING_COL_1
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_2
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_3
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_4
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_5
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_6
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_7
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_8
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_9
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_10
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_11
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_12
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_13
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_14
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_15
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_16
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_17
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_18
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_19
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_20
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_21
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_22
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_23
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_24
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_25
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_26
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_27
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_28
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_29
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_30
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]

  - name: Product/dynamicAttrs/NUM_COL_1
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/NUM_COL_2
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/NUM_COL_3
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/NUM_COL_4
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/NUM_COL_5
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/NUM_COL_6
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/NUM_COL_7
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/NUM_COL_8
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/NUM_COL_9
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/NUM_COL_10
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]

  - name: Product/dynamicAttrs/DATE_COL_1
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
    ## End Product Dynamic Attrs

    ### End Product Fields

    # UI Resource for access to POS tab
  - name: SalesTab
    actions: [VIEW, UPDATE]

    ### Begin POS Fields

  - name: Sales
    group: sales
    actions: [VIEW, UPDATE]

  - name: Sales/sid
    group: sales
    actions: [VIEW]

  - name: Sales/createDate
    group: sales
    actions: [VIEW]

  - name: Sales/updateDate
    group: sales
    actions: [VIEW]

  - name: Sales/customerSid
    group: sales-internal
    actions: [VIEW]

  - name: Sales/deleted
    group: sales-internal
    actions: [VIEW]

  - name: Sales/branchId
    group: sales
    actions: [VIEW]

  - name: Sales/invoiceNumber
    group: sales
    actions: [VIEW]

  - name: Sales/invoiceDate
    group: sales
    actions: [VIEW]

  - name: Sales/quantity
    group: sales
    actions: [VIEW]

  - name: Sales/reportedSku
    group: sales
    actions: [VIEW, UPDATE]

  - name: Sales/productDescription
    group: sales
    actions: [VIEW]

  - name: Sales/transactionId
    group: sales-internal
    actions: [VIEW]

  - name: Sales/vendorPartNumber
    group: sales
    actions: [VIEW]

  - name: Sales/accountRepresentative
    group: sales
    actions: [VIEW]

  - name: Sales/acquisitionExtendedPrice
    group: sales
    actions: [VIEW]

  - name: Sales/acquisitionUnitPrice
    group: sales
    actions: [VIEW]

  - name: Sales/boolExtendedPrice
    group: sales
    actions: [VIEW]

  - name: Sales/bookUnitPrice
    group: sales
    actions: [VIEW]

  - name: Sales/customerOrderNumber
    group: sales
    actions: [VIEW]

  - name: Sales/debitExtendedPrice
    group: sales
    actions: [VIEW]

  - name: Sales/debitUnitPrice
    group: sales
    actions: [VIEW]

  - name: Sales/designRegistrationNumber
    group: sales
    actions: [VIEW]

  - name: Sales/distributorId
    group: sales
    actions: [VIEW]

  - name: Sales/distributorName
    group: sales
    actions: [VIEW]

  - name: Sales/distributorShipmentNumber
    group: sales
    actions: [VIEW]

  - name: Sales/distributorWarehouseId
    group: sales
    actions: [VIEW]

  - name: Sales/exchangeDate
    group: sales
    actions: [VIEW]

  - name: Sales/exchangeRate
    group: sales
    actions: [VIEW]

  - name: Sales/globalProductClassCode
    group: sales
    actions: [VIEW]

  - name: Sales/legacySalesRecordId
    group: sales
    actions: [VIEW]

  - name: Sales/lengthOfProduction
    group: sales
    actions: [VIEW]

  - name: Sales/manufactureId
    group: sales
    actions: [VIEW]

  - name: Sales/manufactureName
    group: sales
    actions: [VIEW]

  - name: Sales/manufacturerShipmentNumber
    group: sales
    actions: [VIEW]

  - name: Sales/orderNumber
    group: sales
    actions: [VIEW]

  - name: Sales/originalId
    group: sales
    actions: [VIEW]

  - name: Sales/price
    group: sales
    actions: [VIEW]

  - name: Sales/purchaseOrderNumber
    group: sales
    actions: [VIEW]

  - name: Sales/r2rDuplicateType
    group: sales
    actions: [VIEW]

  - name: Sales/regionTerritory
    group: sales
    actions: [VIEW]

  - name: Sales/reportEndingDate
    group: sales
    actions: [VIEW]

  - name: Sales/reportType
    group: sales
    actions: [VIEW]

  - name: Sales/resaleExtendedPrice
    group: sales
    actions: [VIEW]

  - name: Sales/resaeExtension
    group: sales
    actions: [VIEW]

  - name: Sales/resaleUnitPrice
    group: sales
    actions: [VIEW]

  - name: Sales/resubmitted
    group: sales
    actions: [VIEW]

  - name: Sales/reportedProductFamily
    group: sales
    actions: [VIEW]

  - name: Sales/reportedProductLine
    group: sales
    actions: [VIEW]

  - name: Sales/reportedProductName
    group: sales
    actions: [VIEW]

  - name: Sales/shipDate
    group: sales
    actions: [VIEW]

  - name: Sales/shipDebitNumber
    group: sales
    actions: [VIEW]

  - name: Sales/shippingMethod
    group: sales
    actions: [VIEW]

  - name: Sales/spaNumber
    group: sales
    actions: [VIEW]

  - name: Sales/tier
    group: sales
    actions: [VIEW]

  - name: Sales/transactionType
    group: sales
    actions: [VIEW]

  - name: Sales/unitOfMeasure
    group: sales
    actions: [VIEW]

  - name: Sales/vendorPartDescription
    group: sales
    actions: [VIEW]

  - name: Sales/validationCodes
    group: sales
    actions: [VIEW]

  - name: Sales/serialNumbers
    group: sales
    actions: [VIEW]

    # Bill to address


  - name: Sales/billToAddress
    group: sales-bill-to
    actions: [VIEW]

  - name: Sales/billToAddress/*
    group: sales-internal
    actions: [VIEW]

  - name: Sales/billToAddress/entityName
    group: sales-bill-to
    actions: [VIEW]

  - name: Sales/billToAddress/street1
    group: sales-bill-to
    actions: [VIEW]

  - name: Sales/billToAddress/street2
    group: sales-bill-to
    actions: [VIEW]

  - name: Sales/billToAddress/city
    group: sales-bill-to
    actions: [VIEW]

  - name: Sales/billToAddress/stateProvince
    group: sales-bill-to
    actions: [VIEW]

  - name: Sales/billToAddress/postalCode
    group: sales-bill-to
    actions: [VIEW]

  - name: Sales/billToAddress/reportedCountry
    group: sales-bill-to
    actions: [VIEW]

  - name: Sales/billToAddress/country
    group: sales-bill-to
    actions: [VIEW]

  - name: Sales/billToAddress/country/name
    group: sales-bill-to
    actions: [VIEW]

  - name: Sales/billToAddress/country/twoCharCode
    group: sales-bill-to
    actions: [VIEW]

  - name: Sales/billToAddress/country/threeCharCode
    group: sales-bill-to
    actions: [VIEW]

  - name: Sales/billToAddressExternalId
    group: sales-bill-to
    actions: [VIEW]

    # sold to address

  - name: Sales/soldToAddress
    group: sales-sold-to
    actions: [VIEW]

  - name: Sales/soldToAddress/*
    group: sales-internal
    actions: [VIEW]

  - name: Sales/soldToAddress/entityName
    group: sales-sold-to
    actions: [VIEW]

  - name: Sales/soldToAddress/street1
    group: sales-sold-to
    actions: [VIEW]

  - name: Sales/soldToAddress/street2
    group: sales-sold-to
    actions: [VIEW]

  - name: Sales/soldToAddress/city
    group: sales-sold-to
    actions: [VIEW]

  - name: Sales/soldToAddress/stateProvince
    group: sales-sold-to
    actions: [VIEW]

  - name: Sales/soldToAddress/postalCode
    group: sales-sold-to
    actions: [VIEW]

  - name: Sales/soldToAddress/reportedCountry
    group: sales-sold-to
    actions: [VIEW]

  - name: Sales/soldToAddress/country
    group: sales-sold-to
    actions: [VIEW]

  - name: Sales/soldToAddress/country/name
    group: sales-sold-to
    actions: [VIEW]

  - name: Sales/soldToAddress/country/twoCharCode
    group: sales-sold-to
    actions: [VIEW]

  - name: Sales/soldToAddress/country/threeCharCode
    group: sales-sold-to
    actions: [VIEW]

  - name: Sales/soldToAddressExternalId
    group: sales-sold-to
    actions: [VIEW]

    # ship to address

  - name: Sales/shipToAddress
    group: sales-ship-to
    actions: [VIEW]

  - name: Sales/shipToAddress/*
    group: sales-internal
    actions: [VIEW]

  - name: Sales/shipToAddress/entityName
    group: sales-ship-to
    actions: [VIEW]

  - name: Sales/shipToAddress/street1
    group: sales-ship-to
    actions: [VIEW]

  - name: Sales/shipToAddress/street2
    group: sales-ship-to
    actions: [VIEW]

  - name: Sales/shipToAddress/city
    group: sales-ship-to
    actions: [VIEW]

  - name: Sales/shipToAddress/stateProvince
    group: sales-ship-to
    actions: [VIEW]

  - name: Sales/shipToAddress/postalCode
    group: sales-ship-to
    actions: [VIEW]

  - name: Sales/shipToAddress/reportedCountry
    group: sales-ship-to
    actions: [VIEW]

  - name: Sales/shipToAddress/country
    group: sales-ship-to
    actions: [VIEW]

  - name: Sales/shipToAddress/country/name
    group: sales-ship-to
    actions: [VIEW]

  - name: Sales/shipToAddress/country/twoCharCode
    group: sales-ship-to
    actions: [VIEW]

  - name: Sales/shipToAddress/country/threeCharCode
    group: sales-ship-to
    actions: [VIEW]

  - name: Sales/shipToAddressExternalId
    group: sales-ship-to
    actions: [VIEW]

    # sell from address

  - name: Sales/sellFromAddress
    group: sales-sell-from
    actions: [VIEW]

  - name: Sales/sellFromAddress/*
    group: sales-internal
    actions: [VIEW]

  - name: Sales/sellFromAddress/entityName
    group: sales-sell-from
    actions: [VIEW]

  - name: Sales/sellFromAddress/street1
    group: sales-sell-from
    actions: [VIEW]

  - name: Sales/sellFromAddress/street2
    group: sales-sell-from
    actions: [VIEW]

  - name: Sales/sellFromAddress/city
    group: sales-sell-from
    actions: [VIEW]

  - name: Sales/sellFromAddress/stateProvince
    group: sales-sell-from
    actions: [VIEW]

  - name: Sales/sellFromAddress/postalCode
    group: sales-sell-from
    actions: [VIEW]

  - name: Sales/sellFromAddress/reportedCountry
    group: sales-sell-from
    actions: [VIEW]

  - name: Sales/sellFromAddress/country
    group: sales-sell-from
    actions: [VIEW]

  - name: Sales/sellFromAddress/country/name
    group: sales-sell-from
    actions: [VIEW]

  - name: Sales/sellFromAddress/country/twoCharCode
    group: sales-sell-from
    actions: [VIEW]

  - name: Sales/sellFromAddress/country/threeCharCode
    group: sales-sell-from
    actions: [VIEW]

  - name: Sales/sellFromAddressExternalId
    group: sales-sell-from
    actions: [VIEW]

    # ship from address

  - name: Sales/shipFromAddress
    group: sales-ship-from
    actions: [VIEW]

  - name: Sales/shipFromAddress/*
    group: sales-internal
    actions: [VIEW]

  - name: Sales/shipFromAddress/entityName
    group: sales-ship-from
    actions: [VIEW]

  - name: Sales/shipFromAddress/street1
    group: sales-ship-from
    actions: [VIEW]

  - name: Sales/shipFromAddress/street2
    group: sales-ship-from
    actions: [VIEW]

  - name: Sales/shipFromAddress/city
    group: sales-ship-from
    actions: [VIEW]

  - name: Sales/shipFromAddress/stateProvince
    group: sales-ship-from
    actions: [VIEW]

  - name: Sales/shipFromAddress/postalCode
    group: sales-ship-from
    actions: [VIEW]

  - name: Sales/shipFromAddress/reportedCountry
    group: sales-ship-from
    actions: [VIEW]

  - name: Sales/shipFromAddress/country
    group: sales-ship-from
    actions: [VIEW]

  - name: Sales/shipFromAddress/country/name
    group: sales-ship-from
    actions: [VIEW]

  - name: Sales/shipFromAddress/country/twoCharCode
    group: sales-ship-from
    actions: [VIEW]

  - name: Sales/shipFromAddress/country/threeCharCode
    group: sales-ship-from
    actions: [VIEW]

  - name: Sales/shipFromAddressExternalId
    group: sales-ship-from
    actions: [VIEW]

    # sales in address

  - name: Sales/salesInAddress
    group: sales-sales-in
    actions: [VIEW]

  - name: Sales/salesInAddress/*
    group: sales-internal
    actions: [VIEW]

  - name: Sales/salesInAddress/entityName
    group: sales-sales-in
    actions: [VIEW]

  - name: Sales/salesInAddress/street1
    group: sales-sales-in
    actions: [VIEW]

  - name: Sales/salesInAddress/street2
    group: sales-sales-in
    actions: [VIEW]

  - name: Sales/salesInAddress/city
    group: sales-sales-in
    actions: [VIEW]

  - name: Sales/salesInAddress/stateProvince
    group: sales-sales-in
    actions: [VIEW]

  - name: Sales/salesInAddress/postalCode
    group: sales-sales-in
    actions: [VIEW]

  - name: Sales/salesInAddress/reportedCountry
    group: sales-sales-in
    actions: [VIEW]

  - name: Sales/salesInAddress/country
    group: sales-sales-in
    actions: [VIEW]

  - name: Sales/salesInAddress/country/name
    group: sales-sales-in
    actions: [VIEW]

  - name: Sales/salesInAddress/country/twoCharCode
    group: sales-sales-in
    actions: [VIEW]

  - name: Sales/salesInAddress/country/threeCharCode
    group: sales-sales-in
    actions: [VIEW]

  - name: Sales/salesInAddressExternalId
    group: sales-sales-in
    actions: [VIEW]

    # purchasing customer address

  - name: Sales/purchasingCustomerAddress
    group: sales-purchasing-customer
    actions: [VIEW]

  - name: Sales/purchasingCustomerAddress/*
    group: sales-internal
    actions: [VIEW]

  - name: Sales/purchasingCustomerAddress/entityName
    group: sales-purchasing-customer
    actions: [VIEW]

  - name: Sales/purchasingCustomerAddress/street1
    group: sales-purchasing-customer
    actions: [VIEW]

  - name: Sales/purchasingCustomerAddress/street2
    group: sales-purchasing-customer
    actions: [VIEW]

  - name: Sales/purchasingCustomerAddress/city
    group: sales-purchasing-customer
    actions: [VIEW]

  - name: Sales/purchasingCustomerAddress/stateProvince
    group: sales-purchasing-customer
    actions: [VIEW]

  - name: Sales/purchasingCustomerAddress/postalCode
    group: sales-purchasing-customer
    actions: [VIEW]

  - name: Sales/purchasingCustomerAddress/reportedCountry
    group: sales-purchasing-customer
    actions: [VIEW]

  - name: Sales/purchasingCustomerAddress/country
    group: sales-purchasing-customer
    actions: [VIEW]

  - name: Sales/purchasingCustomerAddress/country/name
    group: sales-purchasing-customer
    actions: [VIEW]

  - name: Sales/purchasingCustomerAddress/country/twoCharCode
    group: sales-purchasing-customer
    actions: [VIEW]

  - name: Sales/purchasingCustomerAddress/country/threeCharCode
    group: sales-purchasing-customer
    actions: [VIEW]

  - name: Sales/purchasingCustomerExternalId
    group: sales-purchasing-customer
    actions: [VIEW]

    # derived end customer address

  - name: Sales/derivedEndCustomerAddress
    group: sales-derived-end-customer
    actions: [VIEW]

  - name: Sales/derivedEndCustomerAddress/*
    group: sales-internal
    actions: [VIEW]

  - name: Sales/derivedEndCustomerAddress/entityName
    group: sales-derived-end-customer
    actions: [VIEW]

  - name: Sales/derivedEndCustomerAddress/street1
    group: sales-derived-end-customer
    actions: [VIEW]

  - name: Sales/derivedEndCustomerAddress/street2
    group: sales-derived-end-customer
    actions: [VIEW]

  - name: Sales/derivedEndCustomerAddress/city
    group: sales-derived-end-customer
    actions: [VIEW]

  - name: Sales/derivedEndCustomerAddress/stateProvince
    group: sales-derived-end-customer
    actions: [VIEW]

  - name: Sales/derivedEndCustomerAddress/postalCode
    group: sales-derived-end-customer
    actions: [VIEW]

  - name: Sales/derivedEndCustomerAddress/reportedCountry
    group: sales-derived-end-customer
    actions: [VIEW]

  - name: Sales/derivedEndCustomerAddress/country
    group: sales-derived-end-customer
    actions: [VIEW]

  - name: Sales/derivedEndCustomerAddress/country/name
    group: sales-derived-end-customer
    actions: [VIEW]

  - name: Sales/derivedEndCustomerAddress/country/twoCharCode
    group: sales-derived-end-customer
    actions: [VIEW]

  - name: Sales/derivedEndCustomerAddress/country/threeCharCode
    group: sales-derived-end-customer
    actions: [VIEW]

  - name: Sales/derivedEndCustomerAddressExternalId
    group: sales-derived-end-customer
    actions: [VIEW]

    # data file

  - name: Sales/dataFile
    group: sales-data-file
    actions: [VIEW]

  - name: Sales/dataFile/*
    group: sales-internal
    actions: [VIEW]

  - name: Sales/dataFile/loadDate
    group: sales-data-file
    actions: [VIEW]

  - name: Sales/dataFile/reportDate
    group: sales-data-file
    actions: [VIEW]

  - name: Sales/dataFile/id
    group: sales-data-file
    actions: [VIEW]

  - name: Sales/dataFile/fileName
    group: sales-data-file
    actions: [VIEW]

  - name: Sales/dataFile/recordCount
    group: sales-data-file
    actions: [VIEW]

    # match info

  - name: Sales/productMatchInfo
    group: sales-product-match-info
    actions: [VIEW]

  - name: Sales/productMatchInfo/*
    group: sales-internal
    actions: [VIEW]

  - name: Sales/productMatchInfo/matchedProduct
    group: sales-product-match-info
    actions: [VIEW]

  - name: Sales/productMatchInfo/matchedProduct/sku
    group: sales-product-match-info
    actions: [VIEW]

    # reporting partner

  - name: Sales/reportingPartner
    group: sales-reporting-partner
    actions: [VIEW]

  - name: Sales/reportingPartner/*
    group: sales-internal
    actions: [VIEW]

  - name: Sales/reportingPartner/gsNumbers
    group: sales-reporting-partner
    actions: [VIEW]

  - name: Sales/reportingPartner/gsNumbers/value
    group: sales-reporting-partner
    actions: [VIEW]

    # currency

  - name: Sales/currency
    group: sales-currency
    actions: [VIEW]

  - name: Sales/currency/*
    group: sales-internal
    actions: [VIEW]

  - name: Sales/currency/name
    group: sales-currency
    actions: [VIEW]

    # resale currency

  - name: Sales/resaleCurrency
    group: sales-resale-currency
    actions: [VIEW]

  - name: Sales/resaleCurrency/*
    group: sales-internal
    actions: [VIEW]

  - name: Sales/resaleCurrency/name
    group: sales-resale-currency
    actions: [VIEW]

    # debit currency

  - name: Sales/debtCurrency
    group: sales-debit-currency
    actions: [VIEW]

  - name: Sales/debtCurrency/*
    group: sales-internal
    actions: [VIEW]

  - name: Sales/debtCurrency/name
    group: sales-debit-currency
    actions: [VIEW]

    # book currency

  - name: Sales/bookCurrency
    group: sales-book-currency
    actions: [VIEW]

  - name: Sales/bookCurrency/*
    group: sales-internal
    actions: [VIEW]

  - name: Sales/bookCurrency/name
    group: sales-book-currency
    actions: [VIEW]

    # acquisition currency

  - name: Sales/acquisitionCurrency
    group: sales-acquisition-currency
    actions: [VIEW]

  - name: Sales/acquisitionCurrency/*
    group: sales-internal
    actions: [VIEW]

  - name: Sales/acquisitionCurrency/name
    group: sales-acquisition-currency
    actions: [VIEW]

    ## Begin POS Dynamic Attrs

  - name: Sales/dynamicAttrs
    group: sales-dynamic-attrs
    actions: [VIEW, UPDATE]

  - name: Sales/dynamicAttrs/*
    group: sales-dynamic-attrs
    actions: [VIEW, UPDATE]

  - name: Sales/dynamicAttrs/STRING_COL_1
    group: sales-dynamic-attrs
    actions: [VIEW, UPDATE]

    ## End POS Dynamic Attrs

    ### End POS Fields

    # UI Resource for access to INV tab
  - name: InventoryTab
    actions: [VIEW, UPDATE]

    ### Begin INV Fields

  - name: Inventory
    group: inventory
    actions: [VIEW, UPDATE]

  - name: Inventory/sid
    group: inventory
    actions: [VIEW]

  - name: Inventory/createDate
    group: inventory
    actions: [VIEW]

  - name: Inventory/updateDate
    group: inventory
    actions: [VIEW]

  - name: Inventory/customerSid
    group: inventory-internal
    actions: [VIEW]

  - name: Inventory/deleted
    group: inventory-internal
    actions: [VIEW]

  - name: Inventory/productName
    group: inventory
    actions: [VIEW]

  - name: Inventory/clientDescription
    group: inventory
    actions: [VIEW]

  - name: Inventory/clientSku
    group: inventory
    actions: [VIEW, UPDATE]

  - name: Inventory/reportedSku
    group: inventory
    actions: [VIEW]

  - name: Inventory/inventoryDate
    group: inventory
    actions: [VIEW]

  - name: Inventory/unitOfMeasure
    group: inventory
    actions: [VIEW]

  - name: Inventory/id
    group: inventory-internal
    actions: [VIEW]

  - name: Inventory/originalId
    group: inventory
    actions: [VIEW]

  - name: Inventory/lineNumber
    group: inventory-internal
    actions: [VIEW]

    # data file

  - name: Inventory/dataFile
    group: inventory-data-file
    actions: [VIEW]

  - name: Inventory/dataFile/*
    group: inventory-internal
    actions: [VIEW]

  - name: Inventory/dataFile/loadDate
    group: inventory-data-file
    actions: [VIEW]

  - name: Inventory/dataFile/reportDate
    group: inventory-data-file
    actions: [VIEW]

  - name: Inventory/dataFile/id
    group: inventory-data-file
    actions: [VIEW]

  - name: Inventory/dataFile/fileName
    group: inventory-data-file
    actions: [VIEW]

  - name: Inventory/dataFile/recordCount
    group: inventory-data-file
    actions: [VIEW]

    # reporting partner

  - name: Inventory/reportingPartner
    group: inventory-reporting-partner
    actions: [VIEW]

  - name: Inventory/reportingPartner/*
    group: inventory-internal
    actions: [VIEW]

  - name: Inventory/reportingPartner/gsNumbers
    group: inventory-reporting-partner
    actions: [VIEW]

  - name: Inventory/reportingPartner/gsNumbers/value
    group: inventory-reporting-partner
    actions: [VIEW]

    # submission period

  - name: Inventory/submissionPeriod
    group: inventory-submission-period
    actions: [VIEW]

  - name: Inventory/submissionPeriod/*
    group: inventory-internal
    actions: [VIEW]

  - name: Inventory/submissionPeriod/expectedDate
    group: inventory-submission-period
    actions: [VIEW]

  - name: Inventory/submissionPeriod/periodStartDate
    group: inventory-submission-period
    actions: [VIEW]

  - name: Inventory/submissionPeriod/periodEndDate
    group: inventory-submission-period
    actions: [VIEW]

    # quantities

  - name: Inventory/inventoryQuantities
    group: inventory-quantity
    actions: [VIEW]

  - name: Inventory/inventoryQuantities/*
    group: inventory-internal
    actions: [VIEW]

  - name: Inventory/onHandQuantity
    group: inventory-quantity
    actions: [VIEW]

  - name: Inventory/onHandQuantity/*
    group: inventory-internal
    actions: [VIEW]

  - name: Inventory/onHandQuantity/value
    group: inventory-quantity
    actions: [VIEW]

  - name: Inventory/onOrderQuantity
    group: inventory-quantity
    actions: [VIEW]

  - name: Inventory/onOrderQuantity/*
    group: inventory-internal
    actions: [VIEW]

  - name: Inventory/onOrderQuantity/value
    group: inventory-quantity
    actions: [VIEW]

  - name: Inventory/committedQuantity
    group: inventory-quantity
    actions: [VIEW]

  - name: Inventory/committedQuantity/*
    group: inventory-internal
    actions: [VIEW]

  - name: Inventory/committedQuantity/value
    group: inventory-quantity
    actions: [VIEW]

  - name: Inventory/floatQuantity
    group: inventory-quantity
    actions: [VIEW]

  - name: Inventory/floatQuantity/*
    group: inventory-internal
    actions: [VIEW]

  - name: Inventory/floatQuantity/value
    group: inventory-quantity
    actions: [VIEW]

  - name: Inventory/backorderedQuantity
    group: inventory-quantity
    actions: [VIEW]

  - name: Inventory/backorderedQuantity/*
    group: inventory-internal
    actions: [VIEW]

  - name: Inventory/backorderedQuantity/value
    group: inventory-quantity
    actions: [VIEW]

  - name: Inventory/returnedQuantity
    group: inventory-quantity
    actions: [VIEW]

  - name: Inventory/returnedQuantity/*
    group: inventory-internal
    actions: [VIEW]

  - name: Inventory/returnedQuantity/value
    group: inventory-quantity
    actions: [VIEW]

  - name: Inventory/inTransitQuantity
    group: inventory-quantity
    actions: [VIEW]

  - name: Inventory/inTransitQuantity/*
    group: inventory-internal
    actions: [VIEW]

  - name: Inventory/inTransitQuantity/value
    group: inventory-quantity
    actions: [VIEW]

    # prices

  - name: Inventory/inventoryPrices
    group: inventory-price
    actions: [VIEW]

  - name: Inventory/inventoryPrices/*
    group: inventory-internal
    actions: [VIEW]

  - name: Inventory/unitPrice
    group: inventory-price
    actions: [VIEW]

  - name: Inventory/unitPrice/*
    group: inventory-internal
    actions: [VIEW]

  - name: Inventory/unitPrice/price
    group: inventory-price
    actions: [VIEW]

  - name: Inventory/unitPrice/fromCurrency
    group: inventory-price
    actions: [VIEW]

  - name: Inventory/unitPrice/fromCurrency/name
    group: inventory-price
    actions: [VIEW]

  - name: Inventory/unitPrice/toCurrency
    group: inventory-price
    actions: [VIEW]

  - name: Inventory/unitPrice/toCurrency/name
    group: inventory-price
    actions: [VIEW]

    ## Begin INV Dynamic Attrs

  - name: Inventory/dynamicAttrs
    group: inventory-dynamic-attrs
    actions: [VIEW]

  - name: Inventory/dynamicAttrs/*
    group: inventory-dynamic-attrs
    actions: [VIEW]

    ## End INV Dynamic Attrs

    ### End INV Fields

  # UI Resource for access to File Tab
  - name: FilesTab
    actions: [VIEW, UPDATE]

  ## Begin Partner

  - name: Partner
    group: reporting-partner
    actions: [VIEW]

  - name: Partner/*
    group: reporting-partner
    actions: [VIEW]

  ## End Partner

  # Begin File fields
  - name: DataFile
    group: file-management
    actions: [VIEW, UPDATE]

  - name: DataFile/sid
    group: file-management
    actions: [VIEW]

  - name: DataFile/loadDate
    group: file-management
    actions: [VIEW]

  - name: DataFile/reportDate
    group: file-management
    actions: [VIEW]

  - name: DataFile/fileName
    group: file-management
    actions: [VIEW]

  - name: DataFile/fileType
    group: file-management
    actions: [VIEW]

  - name: DataFile/dataType
    group: file-management
    actions: [VIEW]

  - name: DataFile/id
    group: file-management
    actions: [VIEW]

  - name: DataFile/fileSize
    group: file-management
    actions: [VIEW]

  - name: DataFile/source
    group: file-management
    actions: [VIEW]

  - name: DataFile/recordCount
    group: file-management
    actions: [VIEW]

  - name: DataFile/deletedLines
    group: file-management
    actions: [VIEW]

  - name: DataFile/download
    group: file-download
    actions: [VIEW]

  - name: DataFile/validationDownload
    group: file-validation-download
    actions: [VIEW]

  - name: DataFile/upload
    group: file-upload
    actions: [VIEW]

  - name: DataFile/uploadDataTypes
    group: file-upload
    actions: [VIEW]

  - name: DataFile/uploadFileTypes
    group: file-upload
    actions: [VIEW]

  - name: DataFile/reportingPartner
    group: file-reporting-partner
    actions: [VIEW]

  - name: DataFile/reportingPartner/*
    group: file-reporting-partner
    actions: [VIEW]

  - name: DataFile/reportingPartner/partnerOverlayView
    group: file-reporting-partner
    actions: [VIEW]

  - name: DataFile/reportingPartner/partnerOverlayView/*
    group: file-reporting-partner
    actions: [VIEW]

  - name: DataFile/dataFileState
    group: file-data-file-state
    actions: [VIEW]

  - name: DataFile/dataFileState/*
    group: file-data-file-state
    actions: [VIEW]

  - name: DataFile/dataFileState/sid
    group: file-data-file-state
    actions: [VIEW]

  - name: DataFile/dataFileState/createDate
    group: file-data-file-state
    actions: [VIEW]

  - name: DataFile/dataFileState/updateDate
    group: file-data-file-state
    actions: [VIEW]

  - name: DataFile/parserAttempt
    group: file-parser-attempt
    actions: [VIEW]

  - name: DataFile/parserAttempt/*
    group: file-parser-attempt
    actions: [VIEW]

  # End of File fields
  
  # UI Resource for access to Submission Schedule
  - name: SubmissionTrackingTab
    actions: [VIEW, UPDATE]

  - name: SubmissionResultsTab
    actions: [VIEW, UPDATE]

  # Begin Submission Schedule 
  - name: SubmissionSchedule
    group: submission-schedule
    actions: [VIEW, UPDATE]

  - name: SubmissionSchedule/sid
    group: submission-schedule
    actions: [VIEW]

  - name: SubmissionSchedule/createDate
    group: submission-schedule
    actions: [VIEW]

  - name: SubmissionSchedule/updateDate
    group: submission-schedule
    actions: [VIEW]

  - name: SubmissionSchedule/name
    group: submission-schedule
    actions: [VIEW]

  - name: SubmissionSchedule/reportingPartner
    group: ss-reporting-partner
    actions: [VIEW]

  - name: SubmissionSchedule/reportingPartner/*
    group: ss-reporting-partner
    actions: [VIEW]

  - name: SubmissionSchedule/reportingPartner/partnerOverlayView
    group: ss-reporting-partner
    actions: [VIEW]

  - name: SubmissionSchedule/reportingPartner/partnerOverlayView/*
    group: ss-reporting-partner
    actions: [VIEW]

  - name: SubmissionSchedule/dataType
    group: ss-data-type
    actions: [VIEW]

  - name: SubmissionSchedule/dataType/*
    group: ss-data-type
    actions: [VIEW]

  - name: SubmissionSchedule/periodRule
    group: submission-schedule
    actions: [VIEW]

  - name: SubmissionSchedule/expectedDay
    group: submission-schedule
    actions: [VIEW]

  - name: SubmissionSchedule/startDate
    group: submission-schedule
    actions: [VIEW]

  - name: SubmissionSchedule/endDate
    group: submission-schedule
    actions: [VIEW]

  - name: SubmissionSchedule/isInPeriodReporter
    group: submission-schedule
    actions: [VIEW]

  - name: SubmissionSchedule/weekOfMonth
    group: submission-schedule
    actions: [VIEW]

  - name: SubmissionSchedule/monthOfQuarter
    group: submission-schedule
    actions: [VIEW]

  - name: SubmissionSchedule/workingDays
    group: submission-schedule
    actions: [VIEW]

  # End Submission Schedule 

  # Begin Submission Schedule Notification
  - name: SubmissionScheduleNotification
    group: submission-schedule-notification
    actions: [VIEW]
  
  - name: SubmissionScheduleNotification/*
    group: submission-schedule-notification
    actions: [VIEW]

  - name: SubmissionScheduleNotification/notificationType
    group: submission-schedule-notification
    actions: [VIEW]

  - name: SubmissionScheduleNotification/notificationType/*
    group: submission-schedule-notification
    actions: [VIEW]

  - name: SubmissionScheduleNotification/serviceUser
    group: submission-schedule-notification
    actions: [VIEW]

  - name: SubmissionScheduleNotification/serviceUser/*
    group: submission-schedule-notification
    actions: [VIEW]

  # END Submission Schedule Notification

  # Begin Submission Period
  - name: SubmissionPeriod
    group: submission-period-update
    actions: [VIEW, UPDATE]

  - name: SubmissionPeriod/sid
    group: submission-period
    actions: [VIEW]

  - name: SubmissionPeriod/expectedDate
    group: submission-period
    actions: [VIEW]

  - name: SubmissionPeriod/periodStartDate
    group: submission-period
    actions: [VIEW]

  - name: SubmissionPeriod/periodEndDate
    group: submission-period
    actions: [VIEW]

  - name: SubmissionPeriod/createDate
    group: submission-period
    actions: [VIEW]

  - name: SubmissionPeriod/updateDate
    group: submission-period
    actions: [VIEW]

  - name: SubmissionPeriod/noData
    group: submission-period-update
    actions: [VIEW, UPDATE]

  - name: SubmissionPeriod/noDataReason
    group: submission-period-update
    actions: [VIEW, UPDATE]

  - name: SubmissionPeriod/noDataCreateDate
    group: submission-period-update
    actions: [VIEW, UPDATE]

  - name: SubmissionPeriod/onTimeOverride
    group: submission-period
    actions: [VIEW]

  - name: SubmissionPeriod/expectedDay
    group: submission-period
    actions: [VIEW]

  - name: SubmissionPeriod/workingDays
    group: submission-period
    actions: [VIEW]

  - name: SubmissionPeriod/isInPeriodReporter
    group: submission-period
    actions: [VIEW]

  - name: SubmissionPeriod/trackingLevel
    group: submission-period
    actions: [VIEW]

  - name: SubmissionPeriod/status
    group: submission-period
    actions: [VIEW]

  - name: SubmissionPeriod/reportedFlag
    group: submission-period
    actions: [VIEW]

  - name: SubmissionPeriod/fileIds
    group: submission-period
    actions: [VIEW]

  - name: SubmissionPeriod/firstFileName
    group: submission-period
    actions: [VIEW]

  - name: SubmissionPeriod/firstFileCreateDate
    group: submission-period
    actions: [VIEW]

  - name: SubmissionPeriod/firstFileId
    group: submission-period
    actions: [VIEW]

  - name: SubmissionPeriod/deleted
    group: submission-period
    actions: [VIEW]

  - name: SubmissionPeriod/noDataServiceUser
    group: submission-period-update
    actions: [VIEW, UPDATE]

  - name: SubmissionPeriod/noDataServiceUser/sid
    group: sp-no-data-user
    actions: [VIEW]

  - name: SubmissionPeriod/noDataServiceUser/firstName
    group: sp-no-data-user
    actions: [VIEW]

  - name: SubmissionPeriod/noDataServiceUser/lastName
    group: sp-no-data-user
    actions: [VIEW]

  - name: SubmissionPeriod/noDataServiceUser/email
    group: sp-no-data-user
    actions: [VIEW]

  - name: SubmissionPeriod/submissionPeriodLineItemView
    group: submission-period
    actions: [VIEW]

  - name: SubmissionPeriod/submissionPeriodLineItemView/*
    group: submission-period
    actions: [VIEW]

  - name: SubmissionPeriod/dataFileSummaryInfo
    group: submission-period
    actions: [VIEW]

  - name: SubmissionPeriod/dataFileSummaryInfo/*
    group: submission-period
    actions: [VIEW]
    
  - name: SubmissionPeriod/submissionSchedule
    group: submission-period
    actions: [VIEW]
    
  - name: SubmissionPeriod/submissionSchedule/sid
    group: submission-period
    actions: [VIEW]
    
  - name: SubmissionPeriod/submissionSchedule/name
    group: submission-period
    actions: [VIEW]
    
  - name: SubmissionPeriod/submissionSchedule/periodRule
    group: submission-period
    actions: [VIEW]

  - name: SubmissionPeriod/submissionSchedule/reportingPartner
    group: sp-reporting-partner
    actions: [VIEW]

  - name: SubmissionPeriod/submissionSchedule/reportingPartner/*
    group: sp-reporting-partner
    actions: [VIEW]

  - name: SubmissionPeriod/submissionSchedule/reportingPartner/partnerOverlayView
    group: sp-reporting-partner
    actions: [VIEW]

  - name: SubmissionPeriod/submissionSchedule/reportingPartner/partnerOverlayView/*
    group: sp-reporting-partner
    actions: [VIEW]

  - name: SubmissionPeriod/submissionSchedule/dataType
    group: sp-data-type
    actions: [VIEW]

  - name: SubmissionPeriod/submissionSchedule/dataType/*
    group: sp-data-type
    actions: [VIEW]

  # End Submission Period

  # Begin Export Request

  - name: ExportRequest
    group: export
    actions: [VIEW, UPDATE]

  - name: ExportRequest/*
    group: export
    actions: [VIEW, UPDATE]

  # End Export Request

  ### Begin Base resources

  - name: About
    group: about
    actions: [VIEW]

  - name: About/*
    group: about
    actions: [VIEW]

  - name: UserEvent
    group: user-event
    actions: [VIEW, UPDATE]

  - name: UserEvent/*
    group: user-event
    actions: [VIEW, UPDATE]

  - name: ObjectLock
    group: object-lock
    actions: [VIEW, UPDATE]

  - name: ObjectLock/*
    group: object-lock
    actions: [VIEW, UPDATE]

  - name: ObjectLockResponse
    group: object-lock-response
    actions: [VIEW]

  - name: ObjectLockResponse/*
    group: object-lock-response
    actions: [VIEW]

  - name: MutationResponse
    group: mutation-response
    actions: [VIEW]

  - name: MutationResponse/*
    group: mutation-response
    actions: [VIEW]

  - name: DynamicAttrMetadata
    group: attr-metadata
    actions: [VIEW]

  - name: DynamicAttrMetadata/*
    group: attr-metadata
    actions: [VIEW]
    

  ### End Base resources

  ### Begin mutation resources

  - name: Product/mutation/*
    group: product-update
    actions: [UPDATE]

  - name: Sales/mutation/*
    group: sales-update
    actions: [UPDATE]

  - name: Inventory/mutation/*
    group: inventory-update
    actions: [UPDATE]

  - name: ExportRequest/mutation/*
    group: export
    actions: [UPDATE]

  - name: SubmissionPeriod/mutation/*
    group: submission-period-mutation
    actions: [UPDATE]

    ### End mutation resources

    ### Begin Customer Resources

  - name: INT
    actions: [VIEW]

  - name: ACS
    actions: [VIEW]

  - name: CAMB
    actions: [VIEW]

  - name: CYBERDYNE
    actions: [VIEW]

  - name: COR
    actions: [VIEW]

  - name: INT_CCD
    actions: [VIEW]

  - name: ACS_CCD
    actions: [VIEW]

  - name: CAMB_CCD
    actions: [VIEW]

  - name: QCOM_CCD
    actions: [VIEW]

  - name: COR_CCD
    actions: [VIEW]

    ### End Customer Resources

# Common permissions for all tenants
permissions:

  - name: BasicViewUpdate
    displayName: Background Permissions
    description: Every User needs this permission
    resource-actions:
      - about:[VIEW]
      - user-event:[VIEW, UPDATE]
      - object-lock:[VIEW, UPDATE]
      - object-lock-response:[VIEW]
      - mutation-response:[VIEW]
      - attr-metadata:[VIEW]

  - name: KpiView
    displayName: KPI Tab
    description: KPI Permission Set
    resource-actions:
      - ProductKpiTab:[VIEW]

  - name: SSKpiFields
    displayName: Submission KPI Fields
    description: Submission KPI Fields Permission Set
    resource-actions:
      - ssKpi:[VIEW]

  - name: FilesKpiFields
    displayName: Files KPI Fields
    description: Files KPI Fields Permission Set
    resource-actions:
      - filesKpi:[VIEW]

  - name: FileTab
    displayName: File Tab
    description: File Permission Set
    resource-actions:
      - FilesTab:[VIEW]

  - name: FileUploadPartner
    displayName: File Upload for Partner
    description: File Upload Permission Set
    resource-actions:
      - DataFile:[VIEW, UPDATE] 
      - file-upload:[VIEW]     

  - name: FileUpload
    displayName: File Upload 
    description: File Upload Permission Set
    resource-actions:
      - DataFile:[VIEW]
      - file-upload:[VIEW]
      - reporting-partner:[VIEW]

  - name: FileDownload
    displayName: File Download
    description: File Download Permission Set
    resource-actions:
      - DataFile:[VIEW]
      - file-download:[VIEW]
      - file-validation-download:[VIEW]

  - name: SubmissionTab
    displayName: Submission Tab
    description: File Permission Set
    resource-actions:
      - SubmissionTrackingTab:[VIEW]
      - SubmissionResultsTab:[VIEW]

  - name: FileManufactureView
    displayName: File Admin View
    description: File Admin Permission Set
    resource-actions:
      - file-management:[VIEW]
      - file-reporting-partner:[VIEW]
      - file-data-file-state:[VIEW]
      - file-parser-attempt:[VIEW]

  - name: FilePartnerView
    displayName: File Partner View
    description: File Partner Permission Set
    resource-actions:
      - file-management:[VIEW]
      - file-data-file-state:[VIEW]
      - file-parser-attempt:[VIEW]

  - name: SubmissionManufactureView
    displayName: Submission Admin View
    description: Submission Full Permission Set
    resource-actions:
      - submission-schedule:[VIEW]
      - submission-schedule-notification:[VIEW]
      - ss-reporting-partner:[VIEW]
      - ss-data-type:[VIEW]
      - submission-period:[VIEW]
      - sp-reporting-partner:[VIEW]
      - sp-data-type:[VIEW]
      - sp-no-data-user:[VIEW]
      - submission-period-update:[VIEW]

  - name: SubmissionPartnerView
    displayName: Submission Partner View
    description: Submission Full Permission Set
    resource-actions:
      - submission-schedule:[VIEW]
      - submission-schedule-notification:[VIEW]
      - ss-data-type:[VIEW]
      - submission-period:[VIEW]
      - sp-data-type:[VIEW]
      - sp-no-data-user:[VIEW]
      - submission-period-update:[VIEW]

  - name: SubmissionPartnerUpdate
    displayName: Submission Partner Update
    description: Submission Update Permission Set
    resource-actions:
      - submission-period-update:[UPDATE]
      - submission-period-mutation:[UPDATE]

  - name: SubmissionUpdate
    displayName: Submission Update 
    description: Submission Update Permission Set
    resource-actions:
      - submission-period-update:[UPDATE]
      - submission-period-mutation:[UPDATE]
export const SubmissionDef = `
  type Query {
    submissionPeriods(
      offset: Float, 
      limit: Float,
      filters: SubmissionPeriodFilters,
      sort: SubmissionPeriodSort
    ): [SubmissionPeriod]
    submissionSchedules(
      offset: Float, 
      limit: Float,
      filters: SubmissionScheduleFilters, 
      sort: SubmissionScheduleSort
    ): [SubmissionSchedule]
    submissionScheduleNotifications(
      submissionScheduleSid: ID,
      offset: Float,
      limit: Float,
      filters: SubmissionScheduleNotificationFilters,
      sort: SubmissionScheduleNotificationSort
    ): [SubmissionScheduleNotification]
  }

  type Mutation {
    markNoData(data: [NoDataInput]): [MutationResponse] @auth(object: SubmissionPeriod)
  }

  type SubmissionPeriod {
    sid: ID
    createDate: Date
    updateDate: Date
    customerSid: ID
    expectedDate: Date
    periodStartDate: Date
    periodEndDate: Date
    noData: Boolean
    noDataReason: String
    noDataCreateDate: Date
    onTimeOverride: Boolean
    expectedDay: String
    workingDays: String
    isInPeriodReporter: Float
    trackingLevel: String
    submissionSchedule: SubmissionSchedule
    status: String
    reportedFlag: Boolean
    numberOfFiles: Float
    dataFileSummaryInfo: [DataFileSummaryInfo]
    submissionPeriodLineItemView: SubmissionPeriodLineItemView
    noDataServiceUser: ServiceUser
  }

  type SubmissionPeriodLineItemView {
    salesLineItemCount: Float
    invLineItemCount: Float
    earliestFileSubmissionDate: Date
  }

  type DataFileSummaryInfo{
    numberOfPOSLines: Float
    numberOfInventoryLines: Float
    receivedDate: Date
    dataFile: DataFile
  }

  type DataFile{
    fileName: String
    id: String
  }
  
  type SubmissionSchedule {
    sid: ID
    createDate: Date
    updateDate: Date
    customerSid: ID
    dataType: DataType    
    reportingPartner: Partner
    periodRule: String
    name: String
    startDate: Date
    endDate: Date
    expectedDay: String
    workingDays: String
    isInPeriodReporter: Boolean
    weekOfMonth: Float
    monthOfQuarter: Float
  }

  type DataType {
    sid: ID
    createDate: Date
    updateDate: Date
    type: String
  }

  type SubmissionScheduleNotification {
    sid: ID
    createDate: Date
    updateDate: Date
    customerSid: ID
    submissionScheduleSid: ID
    notificationType: NotificationType
    serviceUser: ServiceUser
  }

  enum NotificationType {
    PARSE_SUCCESS
    LATE
    PARSE_FAIL
    EXPECTED
  }

  input SubmissionPeriodFilters {
    sid: IDFilter
    createDate: DateFilter
    updateDate: DateFilter
    customerSid: IDFilter
    expectedDate: DateFilter
    periodStartDate: DateFilter
    periodEndDate: DateFilter
    noDataCreateDate: DateFilter
    submissionSchedule: SubmissionScheduleFilters
    status: StringFilter
    reportedFlag: BooleanFilter
    submissionPeriodLineItemView: SubmissionPeriodLineItemViewFilter
    noData: BooleanFilter
    numberOfFiles: NumberFilter
  }
  
  input SubmissionPeriodLineItemViewFilter {
    salesLineItemCount: NumberFilter
    invLineItemCount: NumberFilter
    earliestFileSubmissionDate: DateFilter
  }

  input SubmissionScheduleFilters {
    sid: IDFilter
    createDate: DateFilter
    updateDate: DateFilter
    customerSid: IDFilter
    reportingPartner: PartnerFilter
    name: StringFilter
    dataType: DataTypeFilter
    periodRule: StringFilter
    expectedDay: StringFilter
    workingDays: StringFilter
    startDate: DateFilter
    endDate: DateFilter
    isInPeriodReporter: BooleanFilter
    weekOfMonth: NumberFilter
    monthOfQuarter: NumberFilter
  }

  input DataTypeFilter {
    sid: IDFilter
    createDate: DateFilter
    updateDate: DateFilter
    type: StringFilter
  }

  input SubmissionScheduleNotificationFilters {
    sid: IDFilter
    createDate: DateFilter
    updateDate: DateFilter
    customerSid: IDFilter
    submissionScheduleSid: IDFilter
    notificationType: StringFilter
    serviceUser: ServiceUserFilters
  }

  input SubmissionPeriodSort {
    sid: SortOption
    createDate: SortOption
    updateDate: SortOption
    expectedDate: SortOption
    periodStartDate: SortOption
    periodEndDate: SortOption
    noDataCreateDate: SortOption
    submissionSchedule: SubmissionScheduleSort
    status: SortOption
    reportedFlag: SortOption
    submissionPeriodLineItemView: SubmissionPeriodLineItemViewSort
    noData: SortOption
    numberOfFiles: SortOption
  }
  
  input SubmissionPeriodLineItemViewSort {
    salesLineItemCount: SortOption
    invLineItemCount: SortOption
    earliestFileSubmissionDate: SortOption
  }

  input SubmissionScheduleSort {
    sid: SortOption
    createDate: SortOption
    updateDate: SortOption
    customerSid: SortOption
    dataType: DataTypeSort
    reportingPartner: PartnerSort
    periodRule: SortOption
    name: SortOption
    startDate: SortOption
    endDate: SortOption
    expectedDay: SortOption
    workingDays: SortOption
    isInPeriodReporter: SortOption
    weekOfMonth: SortOption
    monthOfQuarter: SortOption
  }

  input DataTypeSort {
    sid: SortOption
    createDate: SortOption
    updateDate: SortOption
    type: SortOption
  }

  input SubmissionScheduleNotificationSort {
    sid: SortOption
    createDate: SortOption
    updateDate: SortOption
    notificationType: SortOption
    serviceUser: ServiceUserSort
  }

  input NoDataInput {
    sid: ID!
    noDataReason: String
  }
`;
export const statusSql = (alias: string) => {
     return `(select
             CASE WHEN ( ${alias}."ON_TIME_OVERRIDE" = 1) 
                  THEN 'On-time'
                  WHEN ( "spli1"."EARLIEST_FILE_SUBMISSION_DATE" < ${alias}."EXPECTED_DATE" )
                  THEN 'On-time'
                  WHEN ( ( ${alias}."NO_DATA" = 1 ) 
                         AND ( ${alias}."NO_DATA_CREATE_DATE" < ${alias}."EXPECTED_DATE"))
                  THEN 'On-time'
                  WHEN ( ${alias}."EXPECTED_DATE" > SYSTIMESTAMP)
                  THEN 'Pending'
                  ELSE 'Late'
             END
             from SUBMISSION_PERIOD "sp1"
             left join SUBMISSION_PERIOD_LINE_ITEM_V "spli1" on 
                                                     "spli1"."SUBMISSION_PERIOD_SID" = "sp1"."SID"
                                                     AND "spli1"."CUSTOMER_SID" = "sp1"."CUSTOMER_SID"
             where "sp1"."SID" = ${alias}."SID"
             AND "sp1"."CUSTOMER_SID" = ${alias}."CUSTOMER_SID")`;
};

export const reportedFlagSql = (alias: string) => {
     return `(select
             CASE WHEN MAX(${alias}."ON_TIME_OVERRIDE") = 1
                  THEN 1
                  WHEN MAX(${alias}."NO_DATA") = 1
                  THEN 1
                  WHEN COUNT("df"."ID") > 0
                  THEN 1
                  ELSE 0
             END
             from SUBMISSION_SCHEDULE "ss1"
             left join DATA_FILE_SUMMARY_INFO "dfsi" on 
                                              "dfsi"."SUBMISSION_PERIOD_SID" = ${alias}."SID"
                                              AND "dfsi"."CUSTOMER_SID" = ${alias}."CUSTOMER_SID"
             left join DATA_TYPE "dt1" on "ss1"."DATA_TYPE_SID" = "dt1"."SID"
             left join DATA_FILE "df" on "dfsi"."CUSTOMER_SID" = "df"."CUSTOMER_SID"
                                 AND "dfsi"."DATA_FILE_SID" = "df"."SID"
                                 AND "df"."DATA_TYPE" = "dt1"."TYPE"  
             where "ss1"."SID" = ${alias}."SUBMISSION_SCHEDULE_SID"
             AND "ss1"."CUSTOMER_SID" = ${alias}."CUSTOMER_SID")`
};

export const fileIdsSql = (alias: string) => { 
    return `(select
             listagg("df"."ID",',') within group (ORDER BY "df"."CREATE_DATE")
             from SUBMISSION_SCHEDULE "ss1"
             left join DATA_FILE_SUMMARY_INFO "dfsi" on 
                                              "dfsi"."SUBMISSION_PERIOD_SID" = ${alias}."SID"
                                              AND "dfsi"."CUSTOMER_SID" = ${alias}."CUSTOMER_SID"
             left join DATA_TYPE "dt1" on "ss1"."DATA_TYPE_SID" = "dt1"."SID"
             left join DATA_FILE "df" on "dfsi"."CUSTOMER_SID" = "df"."CUSTOMER_SID"
                                 AND "dfsi"."DATA_FILE_SID" = "df"."SID"
                                 AND "df"."DELETED" = 0
                                 AND "df"."DATA_TYPE" = "dt1"."TYPE"  
             where "ss1"."SID" = ${alias}."SUBMISSION_SCHEDULE_SID"
             AND "ss1"."CUSTOMER_SID" = ${alias}."CUSTOMER_SID")`
};

export const filesCountSql = (alias: string) => {
     return `(select
      count(df.id) as number_of_files
      from SUBMISSION_SCHEDULE ss1
      left join DATA_FILE_SUMMARY_INFO dfsi on 
                                       dfsi.SUBMISSION_PERIOD_SID =  ${alias}.SID
                                       AND dfsi.CUSTOMER_SID = ${alias}.CUSTOMER_SID
      left join DATA_TYPE dt1 on ss1.DATA_TYPE_SID = dt1.SID
      left join DATA_FILE df on dfsi.CUSTOMER_SID = df.CUSTOMER_SID
                          AND dfsi.DATA_FILE_SID = df.SID
                          AND df.DELETED = 0
                          AND df.DATA_TYPE = dt1.TYPE
      where ss1.SID = ${alias}.SUBMISSION_SCHEDULE_SID
      AND ss1.CUSTOMER_SID= ${alias}.CUSTOMER_SID)`
}
import { Entity, Column, JoinColumn, OneToOne, VirtualColumn, OneToMany } from 'typeorm';
import { CustomerDomainEntity } from '../base/CustomerDomainEntity';
import {
  returnsSubmissionPeriodLineItemView,
  SubmissionPeriodLineItemView
} from './SubmissionPeriodLineItemView';
import {
  reportedFlagSql,
  statusSql,
  fileIdsSql,
  filesCountSql
} from './SubmissionPeriodSql';
import {
  returnsSubmissionSchedule,
  SubmissionSchedule
} from './SubmissionSchedule';
import { ServiceUser, returnsServiceUser } from '../user/ServiceUser';
import { DataFileSummaryInfo } from '../datafile/DataFileSummaryInfo';

export const returnsDataFileSummaryInfo = () => DataFileSummaryInfo;

export const dataFileSummaryInfoInverseSide = (dataFileSummaryInfo) =>
  dataFileSummaryInfo.submissionPeriod;

export const returnsSubmissionPeriod = () => SubmissionPeriod;

@Entity({ name: 'SUBMISSION_PERIOD' })
export class SubmissionPeriod extends CustomerDomainEntity {
  @Column({ name: 'EXPECTED_DATE' })
  expectedDate: Date;

  @Column({ name: 'PERIOD_START_DATE' })
  periodStartDate: Date;

  @Column({ name: 'PERIOD_END_DATE' })
  periodEndDate: Date;

  @Column({ name: 'SUBMISSION_SCHEDULE_SID', select: false })
  submissionScheduleSid: number;

  @Column({ name: 'ON_TIME_OVERRIDE' })
  onTimeOverride: boolean;

  @Column({ name: 'NO_DATA' })
  noData: boolean;

  @Column({ name: 'NO_DATA_REASON' })
  noDataReason: string;

  @Column({ name: 'NO_DATA_CREATE_DATE' })
  noDataCreateDate: Date;

  @Column({ name: 'NO_DATA_SERVICE_USER_SID', select: false })
  noDataServiceUserSid: number;

  @OneToOne(returnsServiceUser)
  @JoinColumn({ name: 'NO_DATA_SERVICE_USER_SID' })
  noDataServiceUser: Promise<ServiceUser>;

  @Column({ name: 'TRACKING_LEVEL' })
  trackingLevel: string;

  @Column({ name: 'EXPECTED_DAY' })
  expectedDay: number;

  @Column({ name: 'WORKING_DAYS' })
  workingDays: string;

  @Column({ name: 'IS_IN_PERIOD_REPORTER' })
  isInPeriodReporter: number;

  @Column({ name: 'DELETED' })
  deleted: boolean;

  @OneToOne(returnsSubmissionSchedule)
  @JoinColumn({ name: 'SUBMISSION_SCHEDULE_SID' })
  submissionSchedule?: Promise<SubmissionSchedule>;

  @VirtualColumn({ query: statusSql })
  status?: string;

  @VirtualColumn({ query: reportedFlagSql })
  reportedFlag: boolean;

  @VirtualColumn( {query : fileIdsSql} )
  fileIds?: string;

  firstFileId?: string;

  firstFileName?: string;

  firstFileCreateDate?: Date;

  @VirtualColumn( {query : filesCountSql} )
  numberOfFiles?: number;

  @OneToMany(returnsDataFileSummaryInfo,dataFileSummaryInfoInverseSide)
  @JoinColumn({ name: 'SID', referencedColumnName: 'submissionPeriodSid' })
  dataFileSummaryInfo?: Promise<DataFileSummaryInfo[]>;

  @OneToOne(returnsSubmissionPeriodLineItemView)
  @JoinColumn({ name: 'SID', referencedColumnName: 'submissionPeriodSid' })
  submissionPeriodLineItemView?: Promise<SubmissionPeriodLineItemView>;

}
import { Customer } from './customer/Customer';
import { Partner } from './partner/Partner';
import { Product } from './product/Product';
import { DynamicAttrs } from './attribute/DynamicAttrs';
import { DynamicAttrMetadata } from './attribute/DynamicAttrMetadata';
import { Sales } from './sales/Sales';
import { Address } from './address/Address';
import { Currency } from './base/Currency';
import { DataFile } from './datafile/DataFile';
import { Country } from './address/Country';
import { SalesMatchInfo } from './sales/SalesMatchInfo';
import { ProductAggr } from './product/ProductAggr';
import { GsNumber } from './partner/GsNumber';
import { Inventory } from './inventory/Inventory';
import { SubmissionPeriod } from './submission/SubmissionPeriod';
import { InventoryQuantity } from './inventory/InventoryQuantity';
import { QuantityType } from './inventory/QuantityType';
import { InventoryPrice } from './inventory/InventoryPrice';
import { UserEvent } from './event/UserEvent';
import { UserSession } from './event/UserSession';
import { DataFileState } from './datafile/DataFileState';
import { ParserAttempt } from './datafile/ParserAttempt';
import { PartnerOverlayView } from './partner/PartnerOverlayView';
import { DataState } from './base/DataState';
import { SubmissionSchedule } from './submission/SubmissionSchedule';
import { DataType } from './base/DataType';
import { SubmissionPeriodLineItemView } from './submission/SubmissionPeriodLineItemView';
import { SubmissionScheduleNotification } from './submission/SubmissionScheduleNotification';
import { ServiceUser } from './user/ServiceUser';
import { AuditEvent } from './event/AuditEvent';
import { SubmissionScheduleAudit } from './submission/SubmissionScheduleAudit';
import { AuditType } from './event/AuditType';
import { DataFileSummaryInfo } from './datafile/DataFileSummaryInfo';

export const entities = [
  Customer,
  GsNumber,
  Partner,
  Product,
  ProductAggr,
  Sales,
  Inventory,
  SubmissionPeriod,
  SubmissionSchedule,
  SubmissionScheduleNotification,
  DataType,
  SubmissionPeriodLineItemView,
  InventoryQuantity,
  QuantityType,
  InventoryPrice,
  SalesMatchInfo,
  Address,
  Country,
  Currency,
  DataFile,
  DataFileState,
  DataState,
  ParserAttempt,
  PartnerOverlayView,
  DynamicAttrs,
  DynamicAttrMetadata,
  UserEvent,
  UserSession,
  ServiceUser,
  AuditEvent,
  SubmissionScheduleAudit,
  AuditType,
  DataFileSummaryInfo
];
import { Entity, Column, ManyToOne, JoinColumn, OneToOne} from 'typeorm';
import { CustomerDomainEntity } from '../base/CustomerDomainEntity';
import { SubmissionPeriod } from '../submission/SubmissionPeriod';
import { DataFile, returnsDataFile } from './DataFile';

export const returnsSubmissionPeriods = () => SubmissionPeriod;
export const returnsSummaryInfo = (submissionPeriod) => submissionPeriod.dataFileSummaryInfo;

@Entity({ name: 'DATA_FILE_SUMMARY_INFO' })
export class DataFileSummaryInfo extends CustomerDomainEntity {

    @ManyToOne(returnsSubmissionPeriods,returnsSummaryInfo)
    @JoinColumn({ name: 'SUBMISSION_PERIOD_SID', referencedColumnName:'sid'})
    submissionPeriod: SubmissionPeriod;

    @Column({name:'DATA_FILE_SID'})
    dataFileSid: number;

    @Column({name: 'CUSTOMER_SID'})
    customerSid: number;

    @Column({name:'NUM_SLIS'})
    numberOfPOSLines: number;

    @Column({name:'NUM_ILIS'})
    numberOfInventoryLines: number;

    @Column({name: 'CREATE_DATE'})
    receivedDate: Date;
    
    @Column({ name: 'SUBMISSION_PERIOD_SID', nullable: true })
    submissionPeriodSid: number;

    @OneToOne(returnsDataFile)
    @JoinColumn({ name: 'DATA_FILE_SID' })
    dataFile?: Promise<DataFile>;
}

import {
  fileIdsSql,
  reportedFlagSql,
  statusSql,
  filesCountSql
} from '../../../../src/domain/submission/SubmissionPeriodSql';

describe('SubmissionPeriodSql Tests', () => {
  test('statusSql', () => {
    const actual = statusSql(`"sp"`);

    expect(actual).toEqual(
      `(select
             CASE WHEN ( "sp"."ON_TIME_OVERRIDE" = 1) 
                  THEN 'On-time'
                  WHEN ( "spli1"."EARLIEST_FILE_SUBMISSION_DATE" < "sp"."EXPECTED_DATE" )
                  THEN 'On-time'
                  WHEN ( ( "sp"."NO_DATA" = 1 ) 
                         AND ( "sp"."NO_DATA_CREATE_DATE" < "sp"."EXPECTED_DATE"))
                  THEN 'On-time'
                  WHEN ( "sp"."EXPECTED_DATE" > SYSTIMESTAMP)
                  THEN 'Pending'
                  ELSE 'Late'
             END
             from SUBMISSION_PERIOD "sp1"
             left join SUBMISSION_PERIOD_LINE_ITEM_V "spli1" on 
                                                     "spli1"."SUBMISSION_PERIOD_SID" = "sp1"."SID"
                                                     AND "spli1"."CUSTOMER_SID" = "sp1"."CUSTOMER_SID"
             where "sp1"."SID" = "sp"."SID"
             AND "sp1"."CUSTOMER_SID" = "sp"."CUSTOMER_SID")`
    );
  });

  
  test('reportedFlagSql', () => {
    const actual = reportedFlagSql(`"sp"`);

    expect(actual).toEqual(
      `(select
             CASE WHEN MAX("sp"."ON_TIME_OVERRIDE") = 1
                  THEN 1
                  WHEN MAX("sp"."NO_DATA") = 1
                  THEN 1
                  WHEN COUNT("df"."ID") > 0
                  THEN 1
                  ELSE 0
             END
             from SUBMISSION_SCHEDULE "ss1"
             left join DATA_FILE_SUMMARY_INFO "dfsi" on 
                                              "dfsi"."SUBMISSION_PERIOD_SID" = "sp"."SID"
                                              AND "dfsi"."CUSTOMER_SID" = "sp"."CUSTOMER_SID"
             left join DATA_TYPE "dt1" on "ss1"."DATA_TYPE_SID" = "dt1"."SID"
             left join DATA_FILE "df" on "dfsi"."CUSTOMER_SID" = "df"."CUSTOMER_SID"
                                 AND "dfsi"."DATA_FILE_SID" = "df"."SID"
                                 AND "df"."DATA_TYPE" = "dt1"."TYPE"  
             where "ss1"."SID" = "sp"."SUBMISSION_SCHEDULE_SID"
             AND "ss1"."CUSTOMER_SID" = "sp"."CUSTOMER_SID")`
    );
  });

  
  test('fileIdsSql', () => {
    const actual = fileIdsSql(`"sp"`);

    expect(actual).toEqual(
      `(select
             listagg("df"."ID",',') within group (ORDER BY "df"."CREATE_DATE")
             from SUBMISSION_SCHEDULE "ss1"
             left join DATA_FILE_SUMMARY_INFO "dfsi" on 
                                              "dfsi"."SUBMISSION_PERIOD_SID" = "sp"."SID"
                                              AND "dfsi"."CUSTOMER_SID" = "sp"."CUSTOMER_SID"
             left join DATA_TYPE "dt1" on "ss1"."DATA_TYPE_SID" = "dt1"."SID"
             left join DATA_FILE "df" on "dfsi"."CUSTOMER_SID" = "df"."CUSTOMER_SID"
                                 AND "dfsi"."DATA_FILE_SID" = "df"."SID"
                                 AND "df"."DELETED" = 0
                                 AND "df"."DATA_TYPE" = "dt1"."TYPE"  
             where "ss1"."SID" = "sp"."SUBMISSION_SCHEDULE_SID"
             AND "ss1"."CUSTOMER_SID" = "sp"."CUSTOMER_SID")`
    );
  });

  test('filesCountSql', () => {
    const actual = filesCountSql(`"sp"`);

    expect(actual).toEqual(
      `(select
      count(df.id) as number_of_files
      from SUBMISSION_SCHEDULE ss1
      left join DATA_FILE_SUMMARY_INFO dfsi on 
                                       dfsi.SUBMISSION_PERIOD_SID =  "sp".SID
                                       AND dfsi.CUSTOMER_SID = "sp".CUSTOMER_SID
      left join DATA_TYPE dt1 on ss1.DATA_TYPE_SID = dt1.SID
      left join DATA_FILE df on dfsi.CUSTOMER_SID = df.CUSTOMER_SID
                          AND dfsi.DATA_FILE_SID = df.SID
                          AND df.DELETED = 0
                          AND df.DATA_TYPE = dt1.TYPE
      where ss1.SID = "sp".SUBMISSION_SCHEDULE_SID
      AND ss1.CUSTOMER_SID= "sp".CUSTOMER_SID)`
    );
  });

});
import 'reflect-metadata';
import {
  dataFileSummaryInfoInverseSide,
  returnsDataFileSummaryInfo,
  returnsSubmissionPeriod,
  SubmissionPeriod
} from '../../../../src/domain/submission/SubmissionPeriod';
import { DataFileSummaryInfo } from '../../../../src/domain/datafile/DataFileSummaryInfo';

describe('Submission Period Unit Tests', () => {

  test('returnsSubmissionPeriod', () => {
    expect(returnsSubmissionPeriod()).toEqual(SubmissionPeriod);
  });

  test('constructor', () => {
    expect(new SubmissionPeriod()).toBeInstanceOf(SubmissionPeriod);
  });

  test('dataFileSummaryInfoInverseSide', () => {
    const dataFileSummaryInfo: DataFileSummaryInfo = new DataFileSummaryInfo();
    expect(dataFileSummaryInfoInverseSide(dataFileSummaryInfo)).toEqual(
      dataFileSummaryInfo.submissionPeriod
    );
  });

  test('returnsDataFileSummaryInfo', () => {
    expect(returnsDataFileSummaryInfo()).toEqual(DataFileSummaryInfo);
  });

});

import { returnsSubmissionPeriods, returnsSummaryInfo } from "../../../../src/domain/datafile/DataFileSummaryInfo";
import { SubmissionPeriod } from "../../../../src/domain/submission/SubmissionPeriod";

describe('Data File Summary Info Tests', () => {
    test('returnsSubmissionPeriods', () => {
      expect(returnsSubmissionPeriods()).toEqual(SubmissionPeriod);
    });

    test('returnsSummaryInfo', () => {
        const submissionPeriod = new SubmissionPeriod();
        expect(returnsSummaryInfo(submissionPeriod)).toEqual(
          submissionPeriod.dataFileSummaryInfo
        );
      });
}
)
// Date with time
GETDATE()
// Just the year
YEAR(GETDATE())
// Date without the time
CAST( GETDATE() AS Date )
select * from information_schema.columns 
where TABLE_SCHEMA ='SCE' and TABLE_NAME like'%Order%' and COLUMN_NAME like'%Order%'

select * from information_schema.columns 
WHERE TABLE_SCHEMA ='SCE' and TABLE_NAME like'vw_ORDERS_1' and COLUMN_NAME like'%Date%'
USE [AdventureWorks];
GO
SELECT name AS [Name], 
       SCHEMA_NAME(schema_id) AS schema_name, 
       type_desc, 
       create_date, 
       modify_date
FROM sys.objects
WHERE type ='u'
SELECT catalog_name AS DBName, 
    Schema_name, 
    schema_owner
FROM information_schema.SCHEMATA;
SELECT * from INFORMATION_SCHEMA.VIEWS
version: "1.0"

name: ChannelNetwork

# All actions

actions:
  - name: VIEW
  - name: UPDATE

# All resources

resources:
  # UI Resource for access to kpis tab
  - name: ProductKpiTab
    actions: [VIEW]

    ### Begin productKpi fields

  - name: ProductKpi
    group: productKpi
    actions: [VIEW]

  - name: ProductKpi/*
    group: productKpi
    actions: [VIEW]

    ### End productKpi fields

    ### Begin salesKpi fields

  - name: SalesKpi
    group: salesKpi
    actions: [VIEW]

  - name: SalesKpi/*
    group: salesKpi
    actions: [VIEW]

    ### End salesKpi fields

    ### Begin inventoryKpi fields

  - name: InventoryKpi
    group: inventoryKpi
    actions: [VIEW]

  - name: InventoryKpi/*
    group: inventoryKpi
    actions: [VIEW]

    ### End inventoryKpi fields

    ### Begin filesKpi fields

  - name: FilesKpi
    group: filesKpi
    actions: [VIEW]

  - name: FilesKpi/*
    group: filesKpi
    actions: [VIEW]

    ### End filesKpi fields

    ### Begin ssKpi fields

  - name: SSKpi
    group: ssKpi
    actions: [VIEW]

  - name: SSKpi/*
    group: ssKpi
    actions: [VIEW]

    ### End ssKpi fields


    # UI Resource for access to Products tab
  - name: ProductTab
    actions: [VIEW, UPDATE]

    ### Begin Product Fields

  - name: Product
    group: product
    actions: [VIEW, UPDATE]

  - name: Product/sid
    group: product
    actions: [VIEW]

  - name: Product/createDate
    group: product
    actions: [VIEW]

  - name: Product/updateDate
    group: product
    actions: [VIEW]

  - name: Product/customerSid
    group: product-internal
    actions: [VIEW]

  - name: Product/sku
    group: product
    actions: [VIEW]

  - name: Product/name
    group: product
    actions: [VIEW]

  - name: Product/description
    group: product
    actions: [VIEW]

  - name: Product/productFamily
    group: product
    actions: [VIEW]

  - name: Product/productLine
    group: product
    actions: [VIEW]

  - name: Product/startDate
    group: product
    actions: [VIEW]

  - name: Product/endDate
    group: product
    actions: [VIEW]

  - name: Product/serialized
    group: product-internal
    actions: [VIEW]

  - name: Product/aggregation
    group: product-pos-aggr
    actions: [VIEW]

  - name: Product/aggregation/totalSalesLineCount
    group: product-pos-aggr
    actions: [VIEW]

  - name: Product/aggregation/totalSalesQuantity
    group: product-pos-aggr
    actions: [VIEW]

  - name: Product/aggregation/oldestInvoiceDate
    group: product-pos-aggr
    actions: [VIEW]

    ## Begin Product Dynamic Attrs


  - name: Product/dynamicAttrs
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/sid
    group: product-dynamicAttrs-internal
    actions: [VIEW]
  - name: Product/dynamicAttrs/updateDate
    group: product-dynamicAttrs-internal
    actions: [VIEW]
  - name: Product/dynamicAttrs/createDate
    group: product-dynamicAttrs-internal
    actions: [VIEW]
  - name: Product/dynamicAttrs/attributeType
    group: product-dynamicAttrs-internal
    actions: [VIEW]
  - name: Product/dynamicAttrs/STRING_COL_1
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_2
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_3
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_4
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_5
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_6
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_7
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_8
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_9
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_10
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_11
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_12
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_13
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_14
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_15
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_16
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_17
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_18
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_19
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_20
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_21
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_22
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_23
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_24
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_25
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_26
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_27
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_28
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_29
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_30
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]

  - name: Product/dynamicAttrs/NUM_COL_1
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/NUM_COL_2
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/NUM_COL_3
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/NUM_COL_4
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/NUM_COL_5
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/NUM_COL_6
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/NUM_COL_7
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/NUM_COL_8
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/NUM_COL_9
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/NUM_COL_10
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]

  - name: Product/dynamicAttrs/DATE_COL_1
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
    ## End Product Dynamic Attrs

    ### End Product Fields

    # UI Resource for access to POS tab
  - name: SalesTab
    actions: [VIEW, UPDATE]

    ### Begin POS Fields

  - name: Sales
    group: sales
    actions: [VIEW, UPDATE]

  - name: Sales/sid
    group: sales
    actions: [VIEW]

  - name: Sales/createDate
    group: sales
    actions: [VIEW]

  - name: Sales/updateDate
    group: sales
    actions: [VIEW]

  - name: Sales/customerSid
    group: sales-internal
    actions: [VIEW]

  - name: Sales/deleted
    group: sales-internal
    actions: [VIEW]

  - name: Sales/branchId
    group: sales
    actions: [VIEW]

  - name: Sales/invoiceNumber
    group: sales
    actions: [VIEW]

  - name: Sales/invoiceDate
    group: sales
    actions: [VIEW]

  - name: Sales/quantity
    group: sales
    actions: [VIEW]

  - name: Sales/reportedSku
    group: sales
    actions: [VIEW, UPDATE]

  - name: Sales/productDescription
    group: sales
    actions: [VIEW]

  - name: Sales/transactionId
    group: sales-internal
    actions: [VIEW]

  - name: Sales/vendorPartNumber
    group: sales
    actions: [VIEW]

  - name: Sales/accountRepresentative
    group: sales
    actions: [VIEW]

  - name: Sales/acquisitionExtendedPrice
    group: sales
    actions: [VIEW]

  - name: Sales/acquisitionUnitPrice
    group: sales
    actions: [VIEW]

  - name: Sales/boolExtendedPrice
    group: sales
    actions: [VIEW]

  - name: Sales/bookUnitPrice
    group: sales
    actions: [VIEW]

  - name: Sales/customerOrderNumber
    group: sales
    actions: [VIEW]

  - name: Sales/debitExtendedPrice
    group: sales
    actions: [VIEW]

  - name: Sales/debitUnitPrice
    group: sales
    actions: [VIEW]

  - name: Sales/designRegistrationNumber
    group: sales
    actions: [VIEW]

  - name: Sales/distributorId
    group: sales
    actions: [VIEW]

  - name: Sales/distributorName
    group: sales
    actions: [VIEW]

  - name: Sales/distributorShipmentNumber
    group: sales
    actions: [VIEW]

  - name: Sales/distributorWarehouseId
    group: sales
    actions: [VIEW]

  - name: Sales/exchangeDate
    group: sales
    actions: [VIEW]

  - name: Sales/exchangeRate
    group: sales
    actions: [VIEW]

  - name: Sales/globalProductClassCode
    group: sales
    actions: [VIEW]

  - name: Sales/legacySalesRecordId
    group: sales
    actions: [VIEW]

  - name: Sales/lengthOfProduction
    group: sales
    actions: [VIEW]

  - name: Sales/manufactureId
    group: sales
    actions: [VIEW]

  - name: Sales/manufactureName
    group: sales
    actions: [VIEW]

  - name: Sales/manufacturerShipmentNumber
    group: sales
    actions: [VIEW]

  - name: Sales/orderNumber
    group: sales
    actions: [VIEW]

  - name: Sales/originalId
    group: sales
    actions: [VIEW]

  - name: Sales/price
    group: sales
    actions: [VIEW]

  - name: Sales/purchaseOrderNumber
    group: sales
    actions: [VIEW]

  - name: Sales/r2rDuplicateType
    group: sales
    actions: [VIEW]

  - name: Sales/regionTerritory
    group: sales
    actions: [VIEW]

  - name: Sales/reportEndingDate
    group: sales
    actions: [VIEW]

  - name: Sales/reportType
    group: sales
    actions: [VIEW]

  - name: Sales/resaleExtendedPrice
    group: sales
    actions: [VIEW]

  - name: Sales/resaeExtension
    group: sales
    actions: [VIEW]

  - name: Sales/resaleUnitPrice
    group: sales
    actions: [VIEW]

  - name: Sales/resubmitted
    group: sales
    actions: [VIEW]

  - name: Sales/reportedProductFamily
    group: sales
    actions: [VIEW]

  - name: Sales/reportedProductLine
    group: sales
    actions: [VIEW]

  - name: Sales/reportedProductName
    group: sales
    actions: [VIEW]

  - name: Sales/shipDate
    group: sales
    actions: [VIEW]

  - name: Sales/shipDebitNumber
    group: sales
    actions: [VIEW]

  - name: Sales/shippingMethod
    group: sales
    actions: [VIEW]

  - name: Sales/spaNumber
    group: sales
    actions: [VIEW]

  - name: Sales/tier
    group: sales
    actions: [VIEW]

  - name: Sales/transactionType
    group: sales
    actions: [VIEW]

  - name: Sales/unitOfMeasure
    group: sales
    actions: [VIEW]

  - name: Sales/vendorPartDescription
    group: sales
    actions: [VIEW]

  - name: Sales/validationCodes
    group: sales
    actions: [VIEW]

  - name: Sales/serialNumbers
    group: sales
    actions: [VIEW]

    # Bill to address


  - name: Sales/billToAddress
    group: sales-bill-to
    actions: [VIEW]

  - name: Sales/billToAddress/*
    group: sales-internal
    actions: [VIEW]

  - name: Sales/billToAddress/entityName
    group: sales-bill-to
    actions: [VIEW]

  - name: Sales/billToAddress/street1
    group: sales-bill-to
    actions: [VIEW]

  - name: Sales/billToAddress/street2
    group: sales-bill-to
    actions: [VIEW]

  - name: Sales/billToAddress/city
    group: sales-bill-to
    actions: [VIEW]

  - name: Sales/billToAddress/stateProvince
    group: sales-bill-to
    actions: [VIEW]

  - name: Sales/billToAddress/postalCode
    group: sales-bill-to
    actions: [VIEW]

  - name: Sales/billToAddress/reportedCountry
    group: sales-bill-to
    actions: [VIEW]

  - name: Sales/billToAddress/country
    group: sales-bill-to
    actions: [VIEW]

  - name: Sales/billToAddress/country/name
    group: sales-bill-to
    actions: [VIEW]

  - name: Sales/billToAddress/country/twoCharCode
    group: sales-bill-to
    actions: [VIEW]

  - name: Sales/billToAddress/country/threeCharCode
    group: sales-bill-to
    actions: [VIEW]

  - name: Sales/billToAddressExternalId
    group: sales-bill-to
    actions: [VIEW]

    # sold to address

  - name: Sales/soldToAddress
    group: sales-sold-to
    actions: [VIEW]

  - name: Sales/soldToAddress/*
    group: sales-internal
    actions: [VIEW]

  - name: Sales/soldToAddress/entityName
    group: sales-sold-to
    actions: [VIEW]

  - name: Sales/soldToAddress/street1
    group: sales-sold-to
    actions: [VIEW]

  - name: Sales/soldToAddress/street2
    group: sales-sold-to
    actions: [VIEW]

  - name: Sales/soldToAddress/city
    group: sales-sold-to
    actions: [VIEW]

  - name: Sales/soldToAddress/stateProvince
    group: sales-sold-to
    actions: [VIEW]

  - name: Sales/soldToAddress/postalCode
    group: sales-sold-to
    actions: [VIEW]

  - name: Sales/soldToAddress/reportedCountry
    group: sales-sold-to
    actions: [VIEW]

  - name: Sales/soldToAddress/country
    group: sales-sold-to
    actions: [VIEW]

  - name: Sales/soldToAddress/country/name
    group: sales-sold-to
    actions: [VIEW]

  - name: Sales/soldToAddress/country/twoCharCode
    group: sales-sold-to
    actions: [VIEW]

  - name: Sales/soldToAddress/country/threeCharCode
    group: sales-sold-to
    actions: [VIEW]

  - name: Sales/soldToAddressExternalId
    group: sales-sold-to
    actions: [VIEW]

    # ship to address

  - name: Sales/shipToAddress
    group: sales-ship-to
    actions: [VIEW]

  - name: Sales/shipToAddress/*
    group: sales-internal
    actions: [VIEW]

  - name: Sales/shipToAddress/entityName
    group: sales-ship-to
    actions: [VIEW]

  - name: Sales/shipToAddress/street1
    group: sales-ship-to
    actions: [VIEW]

  - name: Sales/shipToAddress/street2
    group: sales-ship-to
    actions: [VIEW]

  - name: Sales/shipToAddress/city
    group: sales-ship-to
    actions: [VIEW]

  - name: Sales/shipToAddress/stateProvince
    group: sales-ship-to
    actions: [VIEW]

  - name: Sales/shipToAddress/postalCode
    group: sales-ship-to
    actions: [VIEW]

  - name: Sales/shipToAddress/reportedCountry
    group: sales-ship-to
    actions: [VIEW]

  - name: Sales/shipToAddress/country
    group: sales-ship-to
    actions: [VIEW]

  - name: Sales/shipToAddress/country/name
    group: sales-ship-to
    actions: [VIEW]

  - name: Sales/shipToAddress/country/twoCharCode
    group: sales-ship-to
    actions: [VIEW]

  - name: Sales/shipToAddress/country/threeCharCode
    group: sales-ship-to
    actions: [VIEW]

  - name: Sales/shipToAddressExternalId
    group: sales-ship-to
    actions: [VIEW]

    # sell from address

  - name: Sales/sellFromAddress
    group: sales-sell-from
    actions: [VIEW]

  - name: Sales/sellFromAddress/*
    group: sales-internal
    actions: [VIEW]

  - name: Sales/sellFromAddress/entityName
    group: sales-sell-from
    actions: [VIEW]

  - name: Sales/sellFromAddress/street1
    group: sales-sell-from
    actions: [VIEW]

  - name: Sales/sellFromAddress/street2
    group: sales-sell-from
    actions: [VIEW]

  - name: Sales/sellFromAddress/city
    group: sales-sell-from
    actions: [VIEW]

  - name: Sales/sellFromAddress/stateProvince
    group: sales-sell-from
    actions: [VIEW]

  - name: Sales/sellFromAddress/postalCode
    group: sales-sell-from
    actions: [VIEW]

  - name: Sales/sellFromAddress/reportedCountry
    group: sales-sell-from
    actions: [VIEW]

  - name: Sales/sellFromAddress/country
    group: sales-sell-from
    actions: [VIEW]

  - name: Sales/sellFromAddress/country/name
    group: sales-sell-from
    actions: [VIEW]

  - name: Sales/sellFromAddress/country/twoCharCode
    group: sales-sell-from
    actions: [VIEW]

  - name: Sales/sellFromAddress/country/threeCharCode
    group: sales-sell-from
    actions: [VIEW]

  - name: Sales/sellFromAddressExternalId
    group: sales-sell-from
    actions: [VIEW]

    # ship from address

  - name: Sales/shipFromAddress
    group: sales-ship-from
    actions: [VIEW]

  - name: Sales/shipFromAddress/*
    group: sales-internal
    actions: [VIEW]

  - name: Sales/shipFromAddress/entityName
    group: sales-ship-from
    actions: [VIEW]

  - name: Sales/shipFromAddress/street1
    group: sales-ship-from
    actions: [VIEW]

  - name: Sales/shipFromAddress/street2
    group: sales-ship-from
    actions: [VIEW]

  - name: Sales/shipFromAddress/city
    group: sales-ship-from
    actions: [VIEW]

  - name: Sales/shipFromAddress/stateProvince
    group: sales-ship-from
    actions: [VIEW]

  - name: Sales/shipFromAddress/postalCode
    group: sales-ship-from
    actions: [VIEW]

  - name: Sales/shipFromAddress/reportedCountry
    group: sales-ship-from
    actions: [VIEW]

  - name: Sales/shipFromAddress/country
    group: sales-ship-from
    actions: [VIEW]

  - name: Sales/shipFromAddress/country/name
    group: sales-ship-from
    actions: [VIEW]

  - name: Sales/shipFromAddress/country/twoCharCode
    group: sales-ship-from
    actions: [VIEW]

  - name: Sales/shipFromAddress/country/threeCharCode
    group: sales-ship-from
    actions: [VIEW]

  - name: Sales/shipFromAddressExternalId
    group: sales-ship-from
    actions: [VIEW]

    # sales in address

  - name: Sales/salesInAddress
    group: sales-sales-in
    actions: [VIEW]

  - name: Sales/salesInAddress/*
    group: sales-internal
    actions: [VIEW]

  - name: Sales/salesInAddress/entityName
    group: sales-sales-in
    actions: [VIEW]

  - name: Sales/salesInAddress/street1
    group: sales-sales-in
    actions: [VIEW]

  - name: Sales/salesInAddress/street2
    group: sales-sales-in
    actions: [VIEW]

  - name: Sales/salesInAddress/city
    group: sales-sales-in
    actions: [VIEW]

  - name: Sales/salesInAddress/stateProvince
    group: sales-sales-in
    actions: [VIEW]

  - name: Sales/salesInAddress/postalCode
    group: sales-sales-in
    actions: [VIEW]

  - name: Sales/salesInAddress/reportedCountry
    group: sales-sales-in
    actions: [VIEW]

  - name: Sales/salesInAddress/country
    group: sales-sales-in
    actions: [VIEW]

  - name: Sales/salesInAddress/country/name
    group: sales-sales-in
    actions: [VIEW]

  - name: Sales/salesInAddress/country/twoCharCode
    group: sales-sales-in
    actions: [VIEW]

  - name: Sales/salesInAddress/country/threeCharCode
    group: sales-sales-in
    actions: [VIEW]

  - name: Sales/salesInAddressExternalId
    group: sales-sales-in
    actions: [VIEW]

    # purchasing customer address

  - name: Sales/purchasingCustomerAddress
    group: sales-purchasing-customer
    actions: [VIEW]

  - name: Sales/purchasingCustomerAddress/*
    group: sales-internal
    actions: [VIEW]

  - name: Sales/purchasingCustomerAddress/entityName
    group: sales-purchasing-customer
    actions: [VIEW]

  - name: Sales/purchasingCustomerAddress/street1
    group: sales-purchasing-customer
    actions: [VIEW]

  - name: Sales/purchasingCustomerAddress/street2
    group: sales-purchasing-customer
    actions: [VIEW]

  - name: Sales/purchasingCustomerAddress/city
    group: sales-purchasing-customer
    actions: [VIEW]

  - name: Sales/purchasingCustomerAddress/stateProvince
    group: sales-purchasing-customer
    actions: [VIEW]

  - name: Sales/purchasingCustomerAddress/postalCode
    group: sales-purchasing-customer
    actions: [VIEW]

  - name: Sales/purchasingCustomerAddress/reportedCountry
    group: sales-purchasing-customer
    actions: [VIEW]

  - name: Sales/purchasingCustomerAddress/country
    group: sales-purchasing-customer
    actions: [VIEW]

  - name: Sales/purchasingCustomerAddress/country/name
    group: sales-purchasing-customer
    actions: [VIEW]

  - name: Sales/purchasingCustomerAddress/country/twoCharCode
    group: sales-purchasing-customer
    actions: [VIEW]

  - name: Sales/purchasingCustomerAddress/country/threeCharCode
    group: sales-purchasing-customer
    actions: [VIEW]

  - name: Sales/purchasingCustomerExternalId
    group: sales-purchasing-customer
    actions: [VIEW]

    # derived end customer address

  - name: Sales/derivedEndCustomerAddress
    group: sales-derived-end-customer
    actions: [VIEW]

  - name: Sales/derivedEndCustomerAddress/*
    group: sales-internal
    actions: [VIEW]

  - name: Sales/derivedEndCustomerAddress/entityName
    group: sales-derived-end-customer
    actions: [VIEW]

  - name: Sales/derivedEndCustomerAddress/street1
    group: sales-derived-end-customer
    actions: [VIEW]

  - name: Sales/derivedEndCustomerAddress/street2
    group: sales-derived-end-customer
    actions: [VIEW]

  - name: Sales/derivedEndCustomerAddress/city
    group: sales-derived-end-customer
    actions: [VIEW]

  - name: Sales/derivedEndCustomerAddress/stateProvince
    group: sales-derived-end-customer
    actions: [VIEW]

  - name: Sales/derivedEndCustomerAddress/postalCode
    group: sales-derived-end-customer
    actions: [VIEW]

  - name: Sales/derivedEndCustomerAddress/reportedCountry
    group: sales-derived-end-customer
    actions: [VIEW]

  - name: Sales/derivedEndCustomerAddress/country
    group: sales-derived-end-customer
    actions: [VIEW]

  - name: Sales/derivedEndCustomerAddress/country/name
    group: sales-derived-end-customer
    actions: [VIEW]

  - name: Sales/derivedEndCustomerAddress/country/twoCharCode
    group: sales-derived-end-customer
    actions: [VIEW]

  - name: Sales/derivedEndCustomerAddress/country/threeCharCode
    group: sales-derived-end-customer
    actions: [VIEW]

  - name: Sales/derivedEndCustomerAddressExternalId
    group: sales-derived-end-customer
    actions: [VIEW]

    # data file

  - name: Sales/dataFile
    group: sales-data-file
    actions: [VIEW]

  - name: Sales/dataFile/*
    group: sales-internal
    actions: [VIEW]

  - name: Sales/dataFile/loadDate
    group: sales-data-file
    actions: [VIEW]

  - name: Sales/dataFile/reportDate
    group: sales-data-file
    actions: [VIEW]

  - name: Sales/dataFile/id
    group: sales-data-file
    actions: [VIEW]

  - name: Sales/dataFile/fileName
    group: sales-data-file
    actions: [VIEW]

  - name: Sales/dataFile/recordCount
    group: sales-data-file
    actions: [VIEW]

    # match info

  - name: Sales/productMatchInfo
    group: sales-product-match-info
    actions: [VIEW]

  - name: Sales/productMatchInfo/*
    group: sales-internal
    actions: [VIEW]

  - name: Sales/productMatchInfo/matchedProduct
    group: sales-product-match-info
    actions: [VIEW]

  - name: Sales/productMatchInfo/matchedProduct/sku
    group: sales-product-match-info
    actions: [VIEW]

    # reporting partner

  - name: Sales/reportingPartner
    group: sales-reporting-partner
    actions: [VIEW]

  - name: Sales/reportingPartner/*
    group: sales-internal
    actions: [VIEW]

  - name: Sales/reportingPartner/gsNumbers
    group: sales-reporting-partner
    actions: [VIEW]

  - name: Sales/reportingPartner/gsNumbers/value
    group: sales-reporting-partner
    actions: [VIEW]

    # currency

  - name: Sales/currency
    group: sales-currency
    actions: [VIEW]

  - name: Sales/currency/*
    group: sales-internal
    actions: [VIEW]

  - name: Sales/currency/name
    group: sales-currency
    actions: [VIEW]

    # resale currency

  - name: Sales/resaleCurrency
    group: sales-resale-currency
    actions: [VIEW]

  - name: Sales/resaleCurrency/*
    group: sales-internal
    actions: [VIEW]

  - name: Sales/resaleCurrency/name
    group: sales-resale-currency
    actions: [VIEW]

    # debit currency

  - name: Sales/debtCurrency
    group: sales-debit-currency
    actions: [VIEW]

  - name: Sales/debtCurrency/*
    group: sales-internal
    actions: [VIEW]

  - name: Sales/debtCurrency/name
    group: sales-debit-currency
    actions: [VIEW]

    # book currency

  - name: Sales/bookCurrency
    group: sales-book-currency
    actions: [VIEW]

  - name: Sales/bookCurrency/*
    group: sales-internal
    actions: [VIEW]

  - name: Sales/bookCurrency/name
    group: sales-book-currency
    actions: [VIEW]

    # acquisition currency

  - name: Sales/acquisitionCurrency
    group: sales-acquisition-currency
    actions: [VIEW]

  - name: Sales/acquisitionCurrency/*
    group: sales-internal
    actions: [VIEW]

  - name: Sales/acquisitionCurrency/name
    group: sales-acquisition-currency
    actions: [VIEW]

    ## Begin POS Dynamic Attrs

  - name: Sales/dynamicAttrs
    group: sales-dynamic-attrs
    actions: [VIEW, UPDATE]

  - name: Sales/dynamicAttrs/*
    group: sales-dynamic-attrs
    actions: [VIEW, UPDATE]

  - name: Sales/dynamicAttrs/STRING_COL_1
    group: sales-dynamic-attrs
    actions: [VIEW, UPDATE]

    ## End POS Dynamic Attrs

    ### End POS Fields

    # UI Resource for access to INV tab
  - name: InventoryTab
    actions: [VIEW, UPDATE]

    ### Begin INV Fields

  - name: Inventory
    group: inventory
    actions: [VIEW, UPDATE]

  - name: Inventory/sid
    group: inventory
    actions: [VIEW]

  - name: Inventory/createDate
    group: inventory
    actions: [VIEW]

  - name: Inventory/updateDate
    group: inventory
    actions: [VIEW]

  - name: Inventory/customerSid
    group: inventory-internal
    actions: [VIEW]

  - name: Inventory/deleted
    group: inventory-internal
    actions: [VIEW]

  - name: Inventory/productName
    group: inventory
    actions: [VIEW]

  - name: Inventory/clientDescription
    group: inventory
    actions: [VIEW]

  - name: Inventory/clientSku
    group: inventory
    actions: [VIEW, UPDATE]

  - name: Inventory/reportedSku
    group: inventory
    actions: [VIEW]

  - name: Inventory/inventoryDate
    group: inventory
    actions: [VIEW]

  - name: Inventory/unitOfMeasure
    group: inventory
    actions: [VIEW]

  - name: Inventory/id
    group: inventory-internal
    actions: [VIEW]

  - name: Inventory/originalId
    group: inventory
    actions: [VIEW]

  - name: Inventory/lineNumber
    group: inventory-internal
    actions: [VIEW]

    # data file

  - name: Inventory/dataFile
    group: inventory-data-file
    actions: [VIEW]

  - name: Inventory/dataFile/*
    group: inventory-internal
    actions: [VIEW]

  - name: Inventory/dataFile/loadDate
    group: inventory-data-file
    actions: [VIEW]

  - name: Inventory/dataFile/reportDate
    group: inventory-data-file
    actions: [VIEW]

  - name: Inventory/dataFile/id
    group: inventory-data-file
    actions: [VIEW]

  - name: Inventory/dataFile/fileName
    group: inventory-data-file
    actions: [VIEW]

  - name: Inventory/dataFile/recordCount
    group: inventory-data-file
    actions: [VIEW]

    # reporting partner

  - name: Inventory/reportingPartner
    group: inventory-reporting-partner
    actions: [VIEW]

  - name: Inventory/reportingPartner/*
    group: inventory-internal
    actions: [VIEW]

  - name: Inventory/reportingPartner/gsNumbers
    group: inventory-reporting-partner
    actions: [VIEW]

  - name: Inventory/reportingPartner/gsNumbers/value
    group: inventory-reporting-partner
    actions: [VIEW]

    # submission period

  - name: Inventory/submissionPeriod
    group: inventory-submission-period
    actions: [VIEW]

  - name: Inventory/submissionPeriod/*
    group: inventory-internal
    actions: [VIEW]

  - name: Inventory/submissionPeriod/expectedDate
    group: inventory-submission-period
    actions: [VIEW]

  - name: Inventory/submissionPeriod/periodStartDate
    group: inventory-submission-period
    actions: [VIEW]

  - name: Inventory/submissionPeriod/periodEndDate
    group: inventory-submission-period
    actions: [VIEW]

    # quantities

  - name: Inventory/inventoryQuantities
    group: inventory-quantity
    actions: [VIEW]

  - name: Inventory/inventoryQuantities/*
    group: inventory-internal
    actions: [VIEW]

  - name: Inventory/onHandQuantity
    group: inventory-quantity
    actions: [VIEW]

  - name: Inventory/onHandQuantity/*
    group: inventory-internal
    actions: [VIEW]

  - name: Inventory/onHandQuantity/value
    group: inventory-quantity
    actions: [VIEW]

  - name: Inventory/onOrderQuantity
    group: inventory-quantity
    actions: [VIEW]

  - name: Inventory/onOrderQuantity/*
    group: inventory-internal
    actions: [VIEW]

  - name: Inventory/onOrderQuantity/value
    group: inventory-quantity
    actions: [VIEW]

  - name: Inventory/committedQuantity
    group: inventory-quantity
    actions: [VIEW]

  - name: Inventory/committedQuantity/*
    group: inventory-internal
    actions: [VIEW]

  - name: Inventory/committedQuantity/value
    group: inventory-quantity
    actions: [VIEW]

  - name: Inventory/floatQuantity
    group: inventory-quantity
    actions: [VIEW]

  - name: Inventory/floatQuantity/*
    group: inventory-internal
    actions: [VIEW]

  - name: Inventory/floatQuantity/value
    group: inventory-quantity
    actions: [VIEW]

  - name: Inventory/backorderedQuantity
    group: inventory-quantity
    actions: [VIEW]

  - name: Inventory/backorderedQuantity/*
    group: inventory-internal
    actions: [VIEW]

  - name: Inventory/backorderedQuantity/value
    group: inventory-quantity
    actions: [VIEW]

  - name: Inventory/returnedQuantity
    group: inventory-quantity
    actions: [VIEW]

  - name: Inventory/returnedQuantity/*
    group: inventory-internal
    actions: [VIEW]

  - name: Inventory/returnedQuantity/value
    group: inventory-quantity
    actions: [VIEW]

  - name: Inventory/inTransitQuantity
    group: inventory-quantity
    actions: [VIEW]

  - name: Inventory/inTransitQuantity/*
    group: inventory-internal
    actions: [VIEW]

  - name: Inventory/inTransitQuantity/value
    group: inventory-quantity
    actions: [VIEW]

    # prices

  - name: Inventory/inventoryPrices
    group: inventory-price
    actions: [VIEW]

  - name: Inventory/inventoryPrices/*
    group: inventory-internal
    actions: [VIEW]

  - name: Inventory/unitPrice
    group: inventory-price
    actions: [VIEW]

  - name: Inventory/unitPrice/*
    group: inventory-internal
    actions: [VIEW]

  - name: Inventory/unitPrice/price
    group: inventory-price
    actions: [VIEW]

  - name: Inventory/unitPrice/fromCurrency
    group: inventory-price
    actions: [VIEW]

  - name: Inventory/unitPrice/fromCurrency/name
    group: inventory-price
    actions: [VIEW]

  - name: Inventory/unitPrice/toCurrency
    group: inventory-price
    actions: [VIEW]

  - name: Inventory/unitPrice/toCurrency/name
    group: inventory-price
    actions: [VIEW]

    ## Begin INV Dynamic Attrs

  - name: Inventory/dynamicAttrs
    group: inventory-dynamic-attrs
    actions: [VIEW]

  - name: Inventory/dynamicAttrs/*
    group: inventory-dynamic-attrs
    actions: [VIEW]

    ## End INV Dynamic Attrs

    ### End INV Fields

  # UI Resource for access to File Tab
  - name: FilesTab
    actions: [VIEW, UPDATE]

  ## Begin Partner

  - name: Partner
    group: reporting-partner
    actions: [VIEW]

  - name: Partner/*
    group: reporting-partner
    actions: [VIEW]

  ## End Partner

  # Begin File fields
  - name: DataFile
    group: file-management
    actions: [VIEW, UPDATE]

  - name: DataFile/sid
    group: file-management
    actions: [VIEW]

  - name: DataFile/loadDate
    group: file-management
    actions: [VIEW]

  - name: DataFile/reportDate
    group: file-management
    actions: [VIEW]

  - name: DataFile/fileName
    group: file-management
    actions: [VIEW]

  - name: DataFile/fileType
    group: file-management
    actions: [VIEW]

  - name: DataFile/dataType
    group: file-management
    actions: [VIEW]

  - name: DataFile/id
    group: file-management
    actions: [VIEW]

  - name: DataFile/fileSize
    group: file-management
    actions: [VIEW]

  - name: DataFile/source
    group: file-management
    actions: [VIEW]

  - name: DataFile/recordCount
    group: file-management
    actions: [VIEW]

  - name: DataFile/deletedLines
    group: file-management
    actions: [VIEW]

  - name: DataFile/download
    group: file-download
    actions: [VIEW]

  - name: DataFile/validationDownload
    group: file-validation-download
    actions: [VIEW]

  - name: DataFile/upload
    group: file-upload
    actions: [VIEW]

  - name: DataFile/uploadDataTypes
    group: file-upload
    actions: [VIEW]

  - name: DataFile/uploadFileTypes
    group: file-upload
    actions: [VIEW]

  - name: DataFile/reportingPartner
    group: file-reporting-partner
    actions: [VIEW]

  - name: DataFile/reportingPartner/*
    group: file-reporting-partner
    actions: [VIEW]

  - name: DataFile/reportingPartner/partnerOverlayView
    group: file-reporting-partner
    actions: [VIEW]

  - name: DataFile/reportingPartner/partnerOverlayView/*
    group: file-reporting-partner
    actions: [VIEW]

  - name: DataFile/dataFileState
    group: file-data-file-state
    actions: [VIEW]

  - name: DataFile/dataFileState/*
    group: file-data-file-state
    actions: [VIEW]

  - name: DataFile/dataFileState/sid
    group: file-data-file-state
    actions: [VIEW]

  - name: DataFile/dataFileState/createDate
    group: file-data-file-state
    actions: [VIEW]

  - name: DataFile/dataFileState/updateDate
    group: file-data-file-state
    actions: [VIEW]

  - name: DataFile/parserAttempt
    group: file-parser-attempt
    actions: [VIEW]

  - name: DataFile/parserAttempt/*
    group: file-parser-attempt
    actions: [VIEW]

  # End of File fields
  
  # UI Resource for access to Submission Schedule
  - name: SubmissionTrackingTab
    actions: [VIEW, UPDATE]

  - name: SubmissionResultsTab
    actions: [VIEW, UPDATE]

  # Begin Submission Schedule 
  - name: SubmissionSchedule
    group: submission-schedule
    actions: [VIEW, UPDATE]

  - name: SubmissionSchedule/sid
    group: submission-schedule
    actions: [VIEW]

  - name: SubmissionSchedule/createDate
    group: submission-schedule
    actions: [VIEW]

  - name: SubmissionSchedule/updateDate
    group: submission-schedule
    actions: [VIEW]

  - name: SubmissionSchedule/name
    group: submission-schedule
    actions: [VIEW]

  - name: SubmissionSchedule/reportingPartner
    group: ss-reporting-partner
    actions: [VIEW]

  - name: SubmissionSchedule/reportingPartner/*
    group: ss-reporting-partner
    actions: [VIEW]

  - name: SubmissionSchedule/reportingPartner/partnerOverlayView
    group: ss-reporting-partner
    actions: [VIEW]

  - name: SubmissionSchedule/reportingPartner/partnerOverlayView/*
    group: ss-reporting-partner
    actions: [VIEW]

  - name: SubmissionSchedule/dataType
    group: ss-data-type
    actions: [VIEW]

  - name: SubmissionSchedule/dataType/*
    group: ss-data-type
    actions: [VIEW]

  - name: SubmissionSchedule/periodRule
    group: submission-schedule
    actions: [VIEW]

  - name: SubmissionSchedule/expectedDay
    group: submission-schedule
    actions: [VIEW]

  - name: SubmissionSchedule/startDate
    group: submission-schedule
    actions: [VIEW]

  - name: SubmissionSchedule/endDate
    group: submission-schedule
    actions: [VIEW]

  - name: SubmissionSchedule/isInPeriodReporter
    group: submission-schedule
    actions: [VIEW]

  - name: SubmissionSchedule/weekOfMonth
    group: submission-schedule
    actions: [VIEW]

  - name: SubmissionSchedule/monthOfQuarter
    group: submission-schedule
    actions: [VIEW]

  - name: SubmissionSchedule/workingDays
    group: submission-schedule
    actions: [VIEW]

  # End Submission Schedule 

  # Begin Submission Schedule Notification
  - name: SubmissionScheduleNotification
    group: submission-schedule-notification
    actions: [VIEW]
  
  - name: SubmissionScheduleNotification/*
    group: submission-schedule-notification
    actions: [VIEW]

  - name: SubmissionScheduleNotification/notificationType
    group: submission-schedule-notification
    actions: [VIEW]

  - name: SubmissionScheduleNotification/notificationType/*
    group: submission-schedule-notification
    actions: [VIEW]

  - name: SubmissionScheduleNotification/serviceUser
    group: submission-schedule-notification
    actions: [VIEW]

  - name: SubmissionScheduleNotification/serviceUser/*
    group: submission-schedule-notification
    actions: [VIEW]

  # END Submission Schedule Notification

  # Begin Submission Period
  - name: SubmissionPeriod
    group: submission-period-update
    actions: [VIEW, UPDATE]

  - name: SubmissionPeriod/sid
    group: submission-period
    actions: [VIEW]

  - name: SubmissionPeriod/expectedDate
    group: submission-period
    actions: [VIEW]

  - name: SubmissionPeriod/periodStartDate
    group: submission-period
    actions: [VIEW]

  - name: SubmissionPeriod/periodEndDate
    group: submission-period
    actions: [VIEW]

  - name: SubmissionPeriod/createDate
    group: submission-period
    actions: [VIEW]

  - name: SubmissionPeriod/updateDate
    group: submission-period
    actions: [VIEW]

  - name: SubmissionPeriod/noData
    group: submission-period-update
    actions: [VIEW, UPDATE]

  - name: SubmissionPeriod/noDataReason
    group: submission-period-update
    actions: [VIEW, UPDATE]

  - name: SubmissionPeriod/noDataCreateDate
    group: submission-period-update
    actions: [VIEW, UPDATE]

  - name: SubmissionPeriod/onTimeOverride
    group: submission-period
    actions: [VIEW]

  - name: SubmissionPeriod/expectedDay
    group: submission-period
    actions: [VIEW]

  - name: SubmissionPeriod/workingDays
    group: submission-period
    actions: [VIEW]

  - name: SubmissionPeriod/isInPeriodReporter
    group: submission-period
    actions: [VIEW]

  - name: SubmissionPeriod/trackingLevel
    group: submission-period
    actions: [VIEW]

  - name: SubmissionPeriod/status
    group: submission-period
    actions: [VIEW]

  - name: SubmissionPeriod/reportedFlag
    group: submission-period
    actions: [VIEW]

  - name: SubmissionPeriod/fileIds
    group: submission-period
    actions: [VIEW]

  - name: SubmissionPeriod/firstFileName
    group: submission-period
    actions: [VIEW]

  - name: SubmissionPeriod/firstFileCreateDate
    group: submission-period
    actions: [VIEW]

  - name: SubmissionPeriod/firstFileId
    group: submission-period
    actions: [VIEW]

  - name: SubmissionPeriod/deleted
    group: submission-period
    actions: [VIEW]

  - name: SubmissionPeriod/noDataServiceUser
    group: submission-period-update
    actions: [VIEW, UPDATE]

  - name: SubmissionPeriod/noDataServiceUser/sid
    group: sp-no-data-user
    actions: [VIEW]

  - name: SubmissionPeriod/noDataServiceUser/firstName
    group: sp-no-data-user
    actions: [VIEW]

  - name: SubmissionPeriod/noDataServiceUser/lastName
    group: sp-no-data-user
    actions: [VIEW]

  - name: SubmissionPeriod/noDataServiceUser/email
    group: sp-no-data-user
    actions: [VIEW]

  - name: SubmissionPeriod/submissionPeriodLineItemView
    group: submission-period
    actions: [VIEW]

  - name: SubmissionPeriod/submissionPeriodLineItemView/*
    group: submission-period
    actions: [VIEW]

  - name: SubmissionPeriod/dataFileSummaryInfo
    group: submission-period
    actions: [VIEW]

  - name: SubmissionPeriod/dataFileSummaryInfo/*
    group: submission-period
    actions: [VIEW]
    
  - name: SubmissionPeriod/submissionSchedule
    group: submission-period
    actions: [VIEW]
    
  - name: SubmissionPeriod/submissionSchedule/sid
    group: submission-period
    actions: [VIEW]
    
  - name: SubmissionPeriod/submissionSchedule/name
    group: submission-period
    actions: [VIEW]
    
  - name: SubmissionPeriod/submissionSchedule/periodRule
    group: submission-period
    actions: [VIEW]

  - name: SubmissionPeriod/submissionSchedule/reportingPartner
    group: sp-reporting-partner
    actions: [VIEW]

  - name: SubmissionPeriod/submissionSchedule/reportingPartner/*
    group: sp-reporting-partner
    actions: [VIEW]

  - name: SubmissionPeriod/submissionSchedule/reportingPartner/partnerOverlayView
    group: sp-reporting-partner
    actions: [VIEW]

  - name: SubmissionPeriod/submissionSchedule/reportingPartner/partnerOverlayView/*
    group: sp-reporting-partner
    actions: [VIEW]

  - name: SubmissionPeriod/submissionSchedule/dataType
    group: sp-data-type
    actions: [VIEW]

  - name: SubmissionPeriod/submissionSchedule/dataType/*
    group: sp-data-type
    actions: [VIEW]

  # End Submission Period

  # Begin Export Request

  - name: ExportRequest
    group: export
    actions: [VIEW, UPDATE]

  - name: ExportRequest/*
    group: export
    actions: [VIEW, UPDATE]

  # End Export Request

  ### Begin Base resources

  - name: About
    group: about
    actions: [VIEW]

  - name: About/*
    group: about
    actions: [VIEW]

  - name: UserEvent
    group: user-event
    actions: [VIEW, UPDATE]

  - name: UserEvent/*
    group: user-event
    actions: [VIEW, UPDATE]

  - name: ObjectLock
    group: object-lock
    actions: [VIEW, UPDATE]

  - name: ObjectLock/*
    group: object-lock
    actions: [VIEW, UPDATE]

  - name: ObjectLockResponse
    group: object-lock-response
    actions: [VIEW]

  - name: ObjectLockResponse/*
    group: object-lock-response
    actions: [VIEW]

  - name: MutationResponse
    group: mutation-response
    actions: [VIEW]

  - name: MutationResponse/*
    group: mutation-response
    actions: [VIEW]

  - name: DynamicAttrMetadata
    group: attr-metadata
    actions: [VIEW]

  - name: DynamicAttrMetadata/*
    group: attr-metadata
    actions: [VIEW]
    

  ### End Base resources

  ### Begin mutation resources

  - name: Product/mutation/*
    group: product-update
    actions: [UPDATE]

  - name: Sales/mutation/*
    group: sales-update
    actions: [UPDATE]

  - name: Inventory/mutation/*
    group: inventory-update
    actions: [UPDATE]

  - name: ExportRequest/mutation/*
    group: export
    actions: [UPDATE]

  - name: SubmissionPeriod/mutation/*
    group: submission-period-mutation
    actions: [UPDATE]

    ### End mutation resources

    ### Begin Customer Resources

  - name: INT
    actions: [VIEW]

  - name: ACS
    actions: [VIEW]

  - name: CAMB
    actions: [VIEW]

  - name: CYBERDYNE
    actions: [VIEW]

  - name: COR
    actions: [VIEW]

  - name: INT_CCD
    actions: [VIEW]

  - name: ACS_CCD
    actions: [VIEW]

  - name: CAMB_CCD
    actions: [VIEW]

  - name: QCOM_CCD
    actions: [VIEW]

  - name: COR_CCD
    actions: [VIEW]

    ### End Customer Resources

# Common permissions for all tenants
permissions:

  - name: BasicViewUpdate
    displayName: Background Permissions
    description: Every User needs this permission
    resource-actions:
      - about:[VIEW]
      - user-event:[VIEW, UPDATE]
      - object-lock:[VIEW, UPDATE]
      - object-lock-response:[VIEW]
      - mutation-response:[VIEW]
      - attr-metadata:[VIEW]

  - name: KpiView
    displayName: KPI Tab
    description: KPI Permission Set
    resource-actions:
      - ProductKpiTab:[VIEW]

  - name: SSKpiFields
    displayName: Submission KPI Fields
    description: Submission KPI Fields Permission Set
    resource-actions:
      - ssKpi:[VIEW]

  - name: FilesKpiFields
    displayName: Files KPI Fields
    description: Files KPI Fields Permission Set
    resource-actions:
      - filesKpi:[VIEW]

  - name: FileTab
    displayName: File Tab
    description: File Permission Set
    resource-actions:
      - FilesTab:[VIEW]

  - name: FileUploadPartner
    displayName: File Upload for Partner
    description: File Upload Permission Set
    resource-actions:
      - DataFile:[VIEW, UPDATE] 
      - file-upload:[VIEW]     

  - name: FileUpload
    displayName: File Upload 
    description: File Upload Permission Set
    resource-actions:
      - DataFile:[VIEW]
      - file-upload:[VIEW]
      - reporting-partner:[VIEW]

  - name: FileDownload
    displayName: File Download
    description: File Download Permission Set
    resource-actions:
      - DataFile:[VIEW]
      - file-download:[VIEW]
      - file-validation-download:[VIEW]

  - name: SubmissionTab
    displayName: Submission Tab
    description: File Permission Set
    resource-actions:
      - SubmissionTrackingTab:[VIEW]
      - SubmissionResultsTab:[VIEW]

  - name: FileManufactureView
    displayName: File Admin View
    description: File Admin Permission Set
    resource-actions:
      - file-management:[VIEW]
      - file-reporting-partner:[VIEW]
      - file-data-file-state:[VIEW]
      - file-parser-attempt:[VIEW]

  - name: FilePartnerView
    displayName: File Partner View
    description: File Partner Permission Set
    resource-actions:
      - file-management:[VIEW]
      - file-data-file-state:[VIEW]
      - file-parser-attempt:[VIEW]

  - name: SubmissionManufactureView
    displayName: Submission Admin View
    description: Submission Full Permission Set
    resource-actions:
      - submission-schedule:[VIEW]
      - submission-schedule-notification:[VIEW]
      - ss-reporting-partner:[VIEW]
      - ss-data-type:[VIEW]
      - submission-period:[VIEW]
      - sp-reporting-partner:[VIEW]
      - sp-data-type:[VIEW]
      - sp-no-data-user:[VIEW]
      - submission-period-update:[VIEW]

  - name: SubmissionPartnerView
    displayName: Submission Partner View
    description: Submission Full Permission Set
    resource-actions:
      - submission-schedule:[VIEW]
      - submission-schedule-notification:[VIEW]
      - ss-data-type:[VIEW]
      - submission-period:[VIEW]
      - sp-data-type:[VIEW]
      - sp-no-data-user:[VIEW]
      - submission-period-update:[VIEW]

  - name: SubmissionPartnerUpdate
    displayName: Submission Partner Update
    description: Submission Update Permission Set
    resource-actions:
      - submission-period-update:[UPDATE]
      - submission-period-mutation:[UPDATE]

  - name: SubmissionUpdate
    displayName: Submission Update 
    description: Submission Update Permission Set
    resource-actions:
      - submission-period-update:[UPDATE]
      - submission-period-mutation:[UPDATE]
export const SubmissionDef = `
  type Query {
    submissionPeriods(
      offset: Float, 
      limit: Float,
      filters: SubmissionPeriodFilters,
      sort: SubmissionPeriodSort
    ): [SubmissionPeriod]
    submissionSchedules(
      offset: Float, 
      limit: Float,
      filters: SubmissionScheduleFilters, 
      sort: SubmissionScheduleSort
    ): [SubmissionSchedule]
    submissionScheduleNotifications(
      submissionScheduleSid: ID,
      offset: Float,
      limit: Float,
      filters: SubmissionScheduleNotificationFilters,
      sort: SubmissionScheduleNotificationSort
    ): [SubmissionScheduleNotification]
  }

  type Mutation {
    markNoData(data: [NoDataInput]): [MutationResponse] @auth(object: SubmissionPeriod)
  }

  type SubmissionPeriod {
    sid: ID
    createDate: Date
    updateDate: Date
    customerSid: ID
    expectedDate: Date
    periodStartDate: Date
    periodEndDate: Date
    noData: Boolean
    noDataReason: String
    noDataCreateDate: Date
    onTimeOverride: Boolean
    expectedDay: String
    workingDays: String
    isInPeriodReporter: Float
    trackingLevel: String
    submissionSchedule: SubmissionSchedule
    status: String
    reportedFlag: Boolean
    numberOfFiles: Float
    dataFileSummaryInfo: [DataFileSummaryInfo]
    submissionPeriodLineItemView: SubmissionPeriodLineItemView
    noDataServiceUser: ServiceUser
  }

  type SubmissionPeriodLineItemView {
    salesLineItemCount: Float
    invLineItemCount: Float
    earliestFileSubmissionDate: Date
  }

  type DataFileSummaryInfo{
    numberOfPOSLines: Float
    numberOfInventoryLines: Float
    receivedDate: Date
    dataFileId: String
    dataFileName: String
  }
  
  type SubmissionSchedule {
    sid: ID
    createDate: Date
    updateDate: Date
    customerSid: ID
    dataType: DataType    
    reportingPartner: Partner
    periodRule: String
    name: String
    startDate: Date
    endDate: Date
    expectedDay: String
    workingDays: String
    isInPeriodReporter: Boolean
    weekOfMonth: Float
    monthOfQuarter: Float
  }

  type DataType {
    sid: ID
    createDate: Date
    updateDate: Date
    type: String
  }

  type SubmissionScheduleNotification {
    sid: ID
    createDate: Date
    updateDate: Date
    customerSid: ID
    submissionScheduleSid: ID
    notificationType: NotificationType
    serviceUser: ServiceUser
  }

  enum NotificationType {
    PARSE_SUCCESS
    LATE
    PARSE_FAIL
    EXPECTED
  }

  input SubmissionPeriodFilters {
    sid: IDFilter
    createDate: DateFilter
    updateDate: DateFilter
    customerSid: IDFilter
    expectedDate: DateFilter
    periodStartDate: DateFilter
    periodEndDate: DateFilter
    noDataCreateDate: DateFilter
    submissionSchedule: SubmissionScheduleFilters
    status: StringFilter
    reportedFlag: BooleanFilter
    submissionPeriodLineItemView: SubmissionPeriodLineItemViewFilter
    noData: BooleanFilter
    numberOfFiles: NumberFilter
  }
  
  input SubmissionPeriodLineItemViewFilter {
    salesLineItemCount: NumberFilter
    invLineItemCount: NumberFilter
    earliestFileSubmissionDate: DateFilter
  }

  input SubmissionScheduleFilters {
    sid: IDFilter
    createDate: DateFilter
    updateDate: DateFilter
    customerSid: IDFilter
    reportingPartner: PartnerFilter
    name: StringFilter
    dataType: DataTypeFilter
    periodRule: StringFilter
    expectedDay: StringFilter
    workingDays: StringFilter
    startDate: DateFilter
    endDate: DateFilter
    isInPeriodReporter: BooleanFilter
    weekOfMonth: NumberFilter
    monthOfQuarter: NumberFilter
  }

  input DataTypeFilter {
    sid: IDFilter
    createDate: DateFilter
    updateDate: DateFilter
    type: StringFilter
  }

  input SubmissionScheduleNotificationFilters {
    sid: IDFilter
    createDate: DateFilter
    updateDate: DateFilter
    customerSid: IDFilter
    submissionScheduleSid: IDFilter
    notificationType: StringFilter
    serviceUser: ServiceUserFilters
  }

  input SubmissionPeriodSort {
    sid: SortOption
    createDate: SortOption
    updateDate: SortOption
    expectedDate: SortOption
    periodStartDate: SortOption
    periodEndDate: SortOption
    noDataCreateDate: SortOption
    submissionSchedule: SubmissionScheduleSort
    status: SortOption
    reportedFlag: SortOption
    submissionPeriodLineItemView: SubmissionPeriodLineItemViewSort
    noData: SortOption
    numberOfFiles: SortOption
  }
  
  input SubmissionPeriodLineItemViewSort {
    salesLineItemCount: SortOption
    invLineItemCount: SortOption
    earliestFileSubmissionDate: SortOption
  }

  input SubmissionScheduleSort {
    sid: SortOption
    createDate: SortOption
    updateDate: SortOption
    customerSid: SortOption
    dataType: DataTypeSort
    reportingPartner: PartnerSort
    periodRule: SortOption
    name: SortOption
    startDate: SortOption
    endDate: SortOption
    expectedDay: SortOption
    workingDays: SortOption
    isInPeriodReporter: SortOption
    weekOfMonth: SortOption
    monthOfQuarter: SortOption
  }

  input DataTypeSort {
    sid: SortOption
    createDate: SortOption
    updateDate: SortOption
    type: SortOption
  }

  input SubmissionScheduleNotificationSort {
    sid: SortOption
    createDate: SortOption
    updateDate: SortOption
    notificationType: SortOption
    serviceUser: ServiceUserSort
  }

  input NoDataInput {
    sid: ID!
    noDataReason: String
  }
`;
export const statusSql = (alias: string) => {
     return `(select
             CASE WHEN ( ${alias}."ON_TIME_OVERRIDE" = 1) 
                  THEN 'On-time'
                  WHEN ( "spli1"."EARLIEST_FILE_SUBMISSION_DATE" < ${alias}."EXPECTED_DATE" )
                  THEN 'On-time'
                  WHEN ( ( ${alias}."NO_DATA" = 1 ) 
                         AND ( ${alias}."NO_DATA_CREATE_DATE" < ${alias}."EXPECTED_DATE"))
                  THEN 'On-time'
                  WHEN ( ${alias}."EXPECTED_DATE" > SYSTIMESTAMP)
                  THEN 'Pending'
                  ELSE 'Late'
             END
             from SUBMISSION_PERIOD "sp1"
             left join SUBMISSION_PERIOD_LINE_ITEM_V "spli1" on 
                                                     "spli1"."SUBMISSION_PERIOD_SID" = "sp1"."SID"
                                                     AND "spli1"."CUSTOMER_SID" = "sp1"."CUSTOMER_SID"
             where "sp1"."SID" = ${alias}."SID"
             AND "sp1"."CUSTOMER_SID" = ${alias}."CUSTOMER_SID")`;
};

export const reportedFlagSql = (alias: string) => {
     return `(select
             CASE WHEN MAX(${alias}."ON_TIME_OVERRIDE") = 1
                  THEN 1
                  WHEN MAX(${alias}."NO_DATA") = 1
                  THEN 1
                  WHEN COUNT("df"."ID") > 0
                  THEN 1
                  ELSE 0
             END
             from SUBMISSION_SCHEDULE "ss1"
             left join DATA_FILE_SUMMARY_INFO "dfsi" on 
                                              "dfsi"."SUBMISSION_PERIOD_SID" = ${alias}."SID"
                                              AND "dfsi"."CUSTOMER_SID" = ${alias}."CUSTOMER_SID"
             left join DATA_TYPE "dt1" on "ss1"."DATA_TYPE_SID" = "dt1"."SID"
             left join DATA_FILE "df" on "dfsi"."CUSTOMER_SID" = "df"."CUSTOMER_SID"
                                 AND "dfsi"."DATA_FILE_SID" = "df"."SID"
                                 AND "df"."DATA_TYPE" = "dt1"."TYPE"  
             where "ss1"."SID" = ${alias}."SUBMISSION_SCHEDULE_SID"
             AND "ss1"."CUSTOMER_SID" = ${alias}."CUSTOMER_SID")`
};

export const fileIdsSql = (alias: string) => { 
    return `(select
             listagg("df"."ID",',') within group (ORDER BY "df"."CREATE_DATE")
             from SUBMISSION_SCHEDULE "ss1"
             left join DATA_FILE_SUMMARY_INFO "dfsi" on 
                                              "dfsi"."SUBMISSION_PERIOD_SID" = ${alias}."SID"
                                              AND "dfsi"."CUSTOMER_SID" = ${alias}."CUSTOMER_SID"
             left join DATA_TYPE "dt1" on "ss1"."DATA_TYPE_SID" = "dt1"."SID"
             left join DATA_FILE "df" on "dfsi"."CUSTOMER_SID" = "df"."CUSTOMER_SID"
                                 AND "dfsi"."DATA_FILE_SID" = "df"."SID"
                                 AND "df"."DELETED" = 0
                                 AND "df"."DATA_TYPE" = "dt1"."TYPE"  
             where "ss1"."SID" = ${alias}."SUBMISSION_SCHEDULE_SID"
             AND "ss1"."CUSTOMER_SID" = ${alias}."CUSTOMER_SID")`
};

export const filesCountSql = (alias: string) => {
     return `(select
      count(df.id) as number_of_files
      from SUBMISSION_SCHEDULE ss1
      left join DATA_FILE_SUMMARY_INFO dfsi on 
                                       dfsi.SUBMISSION_PERIOD_SID =  ${alias}.SID
                                       AND dfsi.CUSTOMER_SID = ${alias}.CUSTOMER_SID
      left join DATA_TYPE dt1 on ss1.DATA_TYPE_SID = dt1.SID
      left join DATA_FILE df on dfsi.CUSTOMER_SID = df.CUSTOMER_SID
                          AND dfsi.DATA_FILE_SID = df.SID
                          AND df.DELETED = 0
                          AND df.DATA_TYPE = dt1.TYPE
      where ss1.SID = ${alias}.SUBMISSION_SCHEDULE_SID
      AND ss1.CUSTOMER_SID= ${alias}.CUSTOMER_SID)`
}
import { Entity, Column, JoinColumn, OneToOne, VirtualColumn, OneToMany } from 'typeorm';
import { CustomerDomainEntity } from '../base/CustomerDomainEntity';
import {
  returnsSubmissionPeriodLineItemView,
  SubmissionPeriodLineItemView
} from './SubmissionPeriodLineItemView';
import {
  reportedFlagSql,
  statusSql,
  fileIdsSql,
  filesCountSql
} from './SubmissionPeriodSql';
import {
  returnsSubmissionSchedule,
  SubmissionSchedule
} from './SubmissionSchedule';
import { ServiceUser, returnsServiceUser } from '../user/ServiceUser';
import { DataFileSummaryInfo } from '../datafile/DataFileSummaryInfo';

export const returnsDataFileSummaryInfo = () => DataFileSummaryInfo;

export const dataFileSummaryInfoInverseSide = (dataFileSummaryInfo) =>
  dataFileSummaryInfo.submissionPeriod;

export const returnsSubmissionPeriod = () => SubmissionPeriod;

@Entity({ name: 'SUBMISSION_PERIOD' })
export class SubmissionPeriod extends CustomerDomainEntity {
  @Column({ name: 'EXPECTED_DATE' })
  expectedDate: Date;

  @Column({ name: 'PERIOD_START_DATE' })
  periodStartDate: Date;

  @Column({ name: 'PERIOD_END_DATE' })
  periodEndDate: Date;

  @Column({ name: 'SUBMISSION_SCHEDULE_SID', select: false })
  submissionScheduleSid: number;

  @Column({ name: 'ON_TIME_OVERRIDE' })
  onTimeOverride: boolean;

  @Column({ name: 'NO_DATA' })
  noData: boolean;

  @Column({ name: 'NO_DATA_REASON' })
  noDataReason: string;

  @Column({ name: 'NO_DATA_CREATE_DATE' })
  noDataCreateDate: Date;

  @Column({ name: 'NO_DATA_SERVICE_USER_SID', select: false })
  noDataServiceUserSid: number;

  @OneToOne(returnsServiceUser)
  @JoinColumn({ name: 'NO_DATA_SERVICE_USER_SID' })
  noDataServiceUser: Promise<ServiceUser>;

  @Column({ name: 'TRACKING_LEVEL' })
  trackingLevel: string;

  @Column({ name: 'EXPECTED_DAY' })
  expectedDay: number;

  @Column({ name: 'WORKING_DAYS' })
  workingDays: string;

  @Column({ name: 'IS_IN_PERIOD_REPORTER' })
  isInPeriodReporter: number;

  @Column({ name: 'DELETED' })
  deleted: boolean;

  @OneToOne(returnsSubmissionSchedule)
  @JoinColumn({ name: 'SUBMISSION_SCHEDULE_SID' })
  submissionSchedule?: Promise<SubmissionSchedule>;

  @VirtualColumn({ query: statusSql })
  status?: string;

  @VirtualColumn({ query: reportedFlagSql })
  reportedFlag: boolean;

  @VirtualColumn( {query : fileIdsSql} )
  fileIds?: string;

  firstFileId?: string;

  firstFileName?: string;

  firstFileCreateDate?: Date;

  @VirtualColumn( {query : filesCountSql} )
  numberOfFiles?: number;

  @OneToMany(returnsDataFileSummaryInfo,dataFileSummaryInfoInverseSide)
  @JoinColumn({ name: 'SID', referencedColumnName: 'submissionPeriodSid' })
  dataFileSummaryInfo?: Promise<DataFileSummaryInfo[]>;

  @OneToOne(returnsSubmissionPeriodLineItemView)
  @JoinColumn({ name: 'SID', referencedColumnName: 'submissionPeriodSid' })
  submissionPeriodLineItemView?: Promise<SubmissionPeriodLineItemView>;

}
import { Customer } from './customer/Customer';
import { Partner } from './partner/Partner';
import { Product } from './product/Product';
import { DynamicAttrs } from './attribute/DynamicAttrs';
import { DynamicAttrMetadata } from './attribute/DynamicAttrMetadata';
import { Sales } from './sales/Sales';
import { Address } from './address/Address';
import { Currency } from './base/Currency';
import { DataFile } from './datafile/DataFile';
import { Country } from './address/Country';
import { SalesMatchInfo } from './sales/SalesMatchInfo';
import { ProductAggr } from './product/ProductAggr';
import { GsNumber } from './partner/GsNumber';
import { Inventory } from './inventory/Inventory';
import { SubmissionPeriod } from './submission/SubmissionPeriod';
import { InventoryQuantity } from './inventory/InventoryQuantity';
import { QuantityType } from './inventory/QuantityType';
import { InventoryPrice } from './inventory/InventoryPrice';
import { UserEvent } from './event/UserEvent';
import { UserSession } from './event/UserSession';
import { DataFileState } from './datafile/DataFileState';
import { ParserAttempt } from './datafile/ParserAttempt';
import { PartnerOverlayView } from './partner/PartnerOverlayView';
import { DataState } from './base/DataState';
import { SubmissionSchedule } from './submission/SubmissionSchedule';
import { DataType } from './base/DataType';
import { SubmissionPeriodLineItemView } from './submission/SubmissionPeriodLineItemView';
import { SubmissionScheduleNotification } from './submission/SubmissionScheduleNotification';
import { ServiceUser } from './user/ServiceUser';
import { AuditEvent } from './event/AuditEvent';
import { SubmissionScheduleAudit } from './submission/SubmissionScheduleAudit';
import { AuditType } from './event/AuditType';
import { DataFileSummaryInfo } from './datafile/DataFileSummaryInfo';

export const entities = [
  Customer,
  GsNumber,
  Partner,
  Product,
  ProductAggr,
  Sales,
  Inventory,
  SubmissionPeriod,
  SubmissionSchedule,
  SubmissionScheduleNotification,
  DataType,
  SubmissionPeriodLineItemView,
  InventoryQuantity,
  QuantityType,
  InventoryPrice,
  SalesMatchInfo,
  Address,
  Country,
  Currency,
  DataFile,
  DataFileState,
  DataState,
  ParserAttempt,
  PartnerOverlayView,
  DynamicAttrs,
  DynamicAttrMetadata,
  UserEvent,
  UserSession,
  ServiceUser,
  AuditEvent,
  SubmissionScheduleAudit,
  AuditType,
  DataFileSummaryInfo
];
export const getDataFileIdSql = (alias: string) => {
    return `SELECT df.id FROM DATA_FILE df WHERE df.SID = ${alias}.DATA_FILE_SID`;
};

export const getDataFileNameSql = (alias: string) => {
    return `SELECT df.file_name FROM DATA_FILE df WHERE df.SID = ${alias}.DATA_FILE_SID`;
};
import { Entity, Column, ManyToOne, JoinColumn, VirtualColumn} from 'typeorm';
import { CustomerDomainEntity } from '../base/CustomerDomainEntity';
import { SubmissionPeriod } from '../submission/SubmissionPeriod';
import { getDataFileIdSql, getDataFileNameSql } from './DataFileSummaryInfoSql';

export const returnsSubmissionPeriods = () => SubmissionPeriod;
export const returnsSummaryInfo = (submissionPeriod) => submissionPeriod.dataFileSummaryInfo;

@Entity({ name: 'DATA_FILE_SUMMARY_INFO' })
export class DataFileSummaryInfo extends CustomerDomainEntity {

    @ManyToOne(returnsSubmissionPeriods,returnsSummaryInfo)
    @JoinColumn({ name: 'SUBMISSION_PERIOD_SID', referencedColumnName:'sid'})
    submissionPeriod: SubmissionPeriod;

    @Column({name:'DATA_FILE_SID'})
    dataFileSid: number;

    @Column({name: 'CUSTOMER_SID'})
    customerSid: number;

    @Column({name:'NUM_SLIS'})
    numberOfPOSLines: number;

    @Column({name:'NUM_ILIS'})
    numberOfInventoryLines: number;

    @Column({name: 'CREATE_DATE'})
    receivedDate: Date;
    
    @Column({ name: 'SUBMISSION_PERIOD_SID', nullable: true })
    submissionPeriodSid: number;

    @VirtualColumn({ query: getDataFileIdSql})
    dataFileId?: string;
    
    @VirtualColumn({ query: getDataFileNameSql})
    dataFileName?: string;
}

import {
  fileIdsSql,
  reportedFlagSql,
  statusSql,
  filesCountSql
} from '../../../../src/domain/submission/SubmissionPeriodSql';

describe('SubmissionPeriodSql Tests', () => {
  test('statusSql', () => {
    const actual = statusSql(`"sp"`);

    expect(actual).toEqual(
      `(select
             CASE WHEN ( "sp"."ON_TIME_OVERRIDE" = 1) 
                  THEN 'On-time'
                  WHEN ( "spli1"."EARLIEST_FILE_SUBMISSION_DATE" < "sp"."EXPECTED_DATE" )
                  THEN 'On-time'
                  WHEN ( ( "sp"."NO_DATA" = 1 ) 
                         AND ( "sp"."NO_DATA_CREATE_DATE" < "sp"."EXPECTED_DATE"))
                  THEN 'On-time'
                  WHEN ( "sp"."EXPECTED_DATE" > SYSTIMESTAMP)
                  THEN 'Pending'
                  ELSE 'Late'
             END
             from SUBMISSION_PERIOD "sp1"
             left join SUBMISSION_PERIOD_LINE_ITEM_V "spli1" on 
                                                     "spli1"."SUBMISSION_PERIOD_SID" = "sp1"."SID"
                                                     AND "spli1"."CUSTOMER_SID" = "sp1"."CUSTOMER_SID"
             where "sp1"."SID" = "sp"."SID"
             AND "sp1"."CUSTOMER_SID" = "sp"."CUSTOMER_SID")`
    );
  });

  
  test('reportedFlagSql', () => {
    const actual = reportedFlagSql(`"sp"`);

    expect(actual).toEqual(
      `(select
             CASE WHEN MAX("sp"."ON_TIME_OVERRIDE") = 1
                  THEN 1
                  WHEN MAX("sp"."NO_DATA") = 1
                  THEN 1
                  WHEN COUNT("df"."ID") > 0
                  THEN 1
                  ELSE 0
             END
             from SUBMISSION_SCHEDULE "ss1"
             left join DATA_FILE_SUMMARY_INFO "dfsi" on 
                                              "dfsi"."SUBMISSION_PERIOD_SID" = "sp"."SID"
                                              AND "dfsi"."CUSTOMER_SID" = "sp"."CUSTOMER_SID"
             left join DATA_TYPE "dt1" on "ss1"."DATA_TYPE_SID" = "dt1"."SID"
             left join DATA_FILE "df" on "dfsi"."CUSTOMER_SID" = "df"."CUSTOMER_SID"
                                 AND "dfsi"."DATA_FILE_SID" = "df"."SID"
                                 AND "df"."DATA_TYPE" = "dt1"."TYPE"  
             where "ss1"."SID" = "sp"."SUBMISSION_SCHEDULE_SID"
             AND "ss1"."CUSTOMER_SID" = "sp"."CUSTOMER_SID")`
    );
  });

  
  test('fileIdsSql', () => {
    const actual = fileIdsSql(`"sp"`);

    expect(actual).toEqual(
      `(select
             listagg("df"."ID",',') within group (ORDER BY "df"."CREATE_DATE")
             from SUBMISSION_SCHEDULE "ss1"
             left join DATA_FILE_SUMMARY_INFO "dfsi" on 
                                              "dfsi"."SUBMISSION_PERIOD_SID" = "sp"."SID"
                                              AND "dfsi"."CUSTOMER_SID" = "sp"."CUSTOMER_SID"
             left join DATA_TYPE "dt1" on "ss1"."DATA_TYPE_SID" = "dt1"."SID"
             left join DATA_FILE "df" on "dfsi"."CUSTOMER_SID" = "df"."CUSTOMER_SID"
                                 AND "dfsi"."DATA_FILE_SID" = "df"."SID"
                                 AND "df"."DELETED" = 0
                                 AND "df"."DATA_TYPE" = "dt1"."TYPE"  
             where "ss1"."SID" = "sp"."SUBMISSION_SCHEDULE_SID"
             AND "ss1"."CUSTOMER_SID" = "sp"."CUSTOMER_SID")`
    );
  });

  test('filesCountSql', () => {
    const actual = filesCountSql(`"sp"`);

    expect(actual).toEqual(
      `(select
      count(df.id) as number_of_files
      from SUBMISSION_SCHEDULE ss1
      left join DATA_FILE_SUMMARY_INFO dfsi on 
                                       dfsi.SUBMISSION_PERIOD_SID =  "sp".SID
                                       AND dfsi.CUSTOMER_SID = "sp".CUSTOMER_SID
      left join DATA_TYPE dt1 on ss1.DATA_TYPE_SID = dt1.SID
      left join DATA_FILE df on dfsi.CUSTOMER_SID = df.CUSTOMER_SID
                          AND dfsi.DATA_FILE_SID = df.SID
                          AND df.DELETED = 0
                          AND df.DATA_TYPE = dt1.TYPE
      where ss1.SID = "sp".SUBMISSION_SCHEDULE_SID
      AND ss1.CUSTOMER_SID= "sp".CUSTOMER_SID)`
    );
  });

});
import 'reflect-metadata';
import {
  dataFileSummaryInfoInverseSide,
  returnsDataFileSummaryInfo,
  returnsSubmissionPeriod,
  SubmissionPeriod
} from '../../../../src/domain/submission/SubmissionPeriod';
import { DataFileSummaryInfo } from '../../../../src/domain/datafile/DataFileSummaryInfo';

describe('Submission Period Unit Tests', () => {

  test('returnsSubmissionPeriod', () => {
    expect(returnsSubmissionPeriod()).toEqual(SubmissionPeriod);
  });

  test('constructor', () => {
    expect(new SubmissionPeriod()).toBeInstanceOf(SubmissionPeriod);
  });

  test('dataFileSummaryInfoInverseSide', () => {
    const dataFileSummaryInfo: DataFileSummaryInfo = new DataFileSummaryInfo();
    expect(dataFileSummaryInfoInverseSide(dataFileSummaryInfo)).toEqual(
      dataFileSummaryInfo.submissionPeriod
    );
  });

  test('returnsDataFileSummaryInfo', () => {
    expect(returnsDataFileSummaryInfo()).toEqual(DataFileSummaryInfo);
  });

});

import { getDataFileIdSql, getDataFileNameSql } from "../../../../src/domain/datafile/DataFileSummaryInfoSql";

describe('DataFileSummaryInfoSql Tests', () => {
    test('getDataFileIdSql', () => {
      const actual = getDataFileIdSql(`"dfsi"`);
  
      expect(actual).toEqual(
        `SELECT df.id FROM DATA_FILE df WHERE df.SID = "dfsi".DATA_FILE_SID`
      );
    });

    test('getDataFileNameSql', () => {
        const actual = getDataFileNameSql(`"dfsi"`);
    
        expect(actual).toEqual(
          `SELECT df.file_name FROM DATA_FILE df WHERE df.SID = "dfsi".DATA_FILE_SID`
        );
      });
}
);
import { returnsSubmissionPeriods, returnsSummaryInfo } from "../../../../src/domain/datafile/DataFileSummaryInfo";
import { SubmissionPeriod } from "../../../../src/domain/submission/SubmissionPeriod";

describe('Data File Summary Info Tests', () => {
    test('returnsSubmissionPeriods', () => {
      expect(returnsSubmissionPeriods()).toEqual(SubmissionPeriod);
    });

    test('returnsSummaryInfo', () => {
        const submissionPeriod = new SubmissionPeriod();
        expect(returnsSummaryInfo(submissionPeriod)).toEqual(
          submissionPeriod.dataFileSummaryInfo
        );
      });
}
)
export const statusSql = (alias: string) => {
     return `(select
             CASE WHEN ( ${alias}."ON_TIME_OVERRIDE" = 1) 
                  THEN 'On-time'
                  WHEN ( "spli1"."EARLIEST_FILE_SUBMISSION_DATE" < ${alias}."EXPECTED_DATE" )
                  THEN 'On-time'
                  WHEN ( ( ${alias}."NO_DATA" = 1 ) 
                         AND ( ${alias}."NO_DATA_CREATE_DATE" < ${alias}."EXPECTED_DATE"))
                  THEN 'On-time'
                  WHEN ( ${alias}."EXPECTED_DATE" > SYSTIMESTAMP)
                  THEN 'Pending'
                  ELSE 'Late'
             END
             from SUBMISSION_PERIOD "sp1"
             left join SUBMISSION_PERIOD_LINE_ITEM_V "spli1" on 
                                                     "spli1"."SUBMISSION_PERIOD_SID" = "sp1"."SID"
                                                     AND "spli1"."CUSTOMER_SID" = "sp1"."CUSTOMER_SID"
             where "sp1"."SID" = ${alias}."SID"
             AND "sp1"."CUSTOMER_SID" = ${alias}."CUSTOMER_SID")`;
};

export const reportedFlagSql = (alias: string) => {
     return `(select
             CASE WHEN MAX(${alias}."ON_TIME_OVERRIDE") = 1
                  THEN 1
                  WHEN MAX(${alias}."NO_DATA") = 1
                  THEN 1
                  WHEN COUNT("df"."ID") > 0
                  THEN 1
                  ELSE 0
             END
             from SUBMISSION_SCHEDULE "ss1"
             left join DATA_FILE_SUMMARY_INFO "dfsi" on 
                                              "dfsi"."SUBMISSION_PERIOD_SID" = ${alias}."SID"
                                              AND "dfsi"."CUSTOMER_SID" = ${alias}."CUSTOMER_SID"
             left join DATA_TYPE "dt1" on "ss1"."DATA_TYPE_SID" = "dt1"."SID"
             left join DATA_FILE "df" on "dfsi"."CUSTOMER_SID" = "df"."CUSTOMER_SID"
                                 AND "dfsi"."DATA_FILE_SID" = "df"."SID"
                                 AND "df"."DATA_TYPE" = "dt1"."TYPE"  
             where "ss1"."SID" = ${alias}."SUBMISSION_SCHEDULE_SID"
             AND "ss1"."CUSTOMER_SID" = ${alias}."CUSTOMER_SID")`
};

export const fileIdsSql = (alias: string) => { 
    return `(select
             listagg("df"."ID",',') within group (ORDER BY "df"."CREATE_DATE")
             from SUBMISSION_SCHEDULE "ss1"
             left join DATA_FILE_SUMMARY_INFO "dfsi" on 
                                              "dfsi"."SUBMISSION_PERIOD_SID" = ${alias}."SID"
                                              AND "dfsi"."CUSTOMER_SID" = ${alias}."CUSTOMER_SID"
             left join DATA_TYPE "dt1" on "ss1"."DATA_TYPE_SID" = "dt1"."SID"
             left join DATA_FILE "df" on "dfsi"."CUSTOMER_SID" = "df"."CUSTOMER_SID"
                                 AND "dfsi"."DATA_FILE_SID" = "df"."SID"
                                 AND "df"."DELETED" = 0
                                 AND "df"."DATA_TYPE" = "dt1"."TYPE"  
             where "ss1"."SID" = ${alias}."SUBMISSION_SCHEDULE_SID"
             AND "ss1"."CUSTOMER_SID" = ${alias}."CUSTOMER_SID")`
};

export const filesCountSql = (alias: string) => {
     return `(select
          count(df.id) as number_of_files
          from SUBMISSION_SCHEDULE ss1
          left join DATA_FILE_SUMMARY_INFO dfsi on 
                                           dfsi.SUBMISSION_PERIOD_SID =  ${alias}.SID
                                           AND dfsi.CUSTOMER_SID = ${alias}.CUSTOMER_SID
          left join DATA_TYPE dt1 on ss1.DATA_TYPE_SID = dt1.SID
          left join DATA_FILE df on dfsi.CUSTOMER_SID = df.CUSTOMER_SID
                              AND dfsi.DATA_FILE_SID = df.SID
                              AND df.DELETED = 0
                              AND df.DATA_TYPE = dt1.TYPE
          where ss1.SID = ${alias}.SUBMISSION_SCHEDULE_SID
          AND ss1.CUSTOMER_SID= ${alias}.CUSTOMER_SID)`
}

export const filesDataSql = (alias:string) => {
     return `(select
          df.id
          from SUBMISSION_SCHEDULE ss1
          left join DATA_FILE_SUMMARY_INFO dfsi on 
                                           dfsi.SUBMISSION_PERIOD_SID = ${alias}.SID
                                           AND dfsi.CUSTOMER_SID = ${alias}.CUSTOMER_SID
          left join DATA_TYPE dt1 on ss1.DATA_TYPE_SID = dt1.SID
          left join DATA_FILE df on dfsi.CUSTOMER_SID = df.CUSTOMER_SID
                              AND dfsi.DATA_FILE_SID = df.SID
                              AND df.DELETED = 0
                              AND df.DATA_TYPE = dt1.TYPE
          where ss1.SID = ${alias}.SUBMISSION_SCHEDULE_SID
          AND ss1.CUSTOMER_SID= ${alias}.CUSTOMER_SID
          AND df.id IS NOT NULL)`
}
version: "1.0"

name: ChannelNetwork

# All actions

actions:
  - name: VIEW
  - name: UPDATE

# All resources

resources:
  # UI Resource for access to kpis tab
  - name: ProductKpiTab
    actions: [VIEW]

    ### Begin productKpi fields

  - name: ProductKpi
    group: productKpi
    actions: [VIEW]

  - name: ProductKpi/*
    group: productKpi
    actions: [VIEW]

    ### End productKpi fields

    ### Begin salesKpi fields

  - name: SalesKpi
    group: salesKpi
    actions: [VIEW]

  - name: SalesKpi/*
    group: salesKpi
    actions: [VIEW]

    ### End salesKpi fields

    ### Begin inventoryKpi fields

  - name: InventoryKpi
    group: inventoryKpi
    actions: [VIEW]

  - name: InventoryKpi/*
    group: inventoryKpi
    actions: [VIEW]

    ### End inventoryKpi fields

    ### Begin filesKpi fields

  - name: FilesKpi
    group: filesKpi
    actions: [VIEW]

  - name: FilesKpi/*
    group: filesKpi
    actions: [VIEW]

    ### End filesKpi fields

    ### Begin ssKpi fields

  - name: SSKpi
    group: ssKpi
    actions: [VIEW]

  - name: SSKpi/*
    group: ssKpi
    actions: [VIEW]

    ### End ssKpi fields


    # UI Resource for access to Products tab
  - name: ProductTab
    actions: [VIEW, UPDATE]

    ### Begin Product Fields

  - name: Product
    group: product
    actions: [VIEW, UPDATE]

  - name: Product/sid
    group: product
    actions: [VIEW]

  - name: Product/createDate
    group: product
    actions: [VIEW]

  - name: Product/updateDate
    group: product
    actions: [VIEW]

  - name: Product/customerSid
    group: product-internal
    actions: [VIEW]

  - name: Product/sku
    group: product
    actions: [VIEW]

  - name: Product/name
    group: product
    actions: [VIEW]

  - name: Product/description
    group: product
    actions: [VIEW]

  - name: Product/productFamily
    group: product
    actions: [VIEW]

  - name: Product/productLine
    group: product
    actions: [VIEW]

  - name: Product/startDate
    group: product
    actions: [VIEW]

  - name: Product/endDate
    group: product
    actions: [VIEW]

  - name: Product/serialized
    group: product-internal
    actions: [VIEW]

  - name: Product/aggregation
    group: product-pos-aggr
    actions: [VIEW]

  - name: Product/aggregation/totalSalesLineCount
    group: product-pos-aggr
    actions: [VIEW]

  - name: Product/aggregation/totalSalesQuantity
    group: product-pos-aggr
    actions: [VIEW]

  - name: Product/aggregation/oldestInvoiceDate
    group: product-pos-aggr
    actions: [VIEW]

    ## Begin Product Dynamic Attrs


  - name: Product/dynamicAttrs
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/sid
    group: product-dynamicAttrs-internal
    actions: [VIEW]
  - name: Product/dynamicAttrs/updateDate
    group: product-dynamicAttrs-internal
    actions: [VIEW]
  - name: Product/dynamicAttrs/createDate
    group: product-dynamicAttrs-internal
    actions: [VIEW]
  - name: Product/dynamicAttrs/attributeType
    group: product-dynamicAttrs-internal
    actions: [VIEW]
  - name: Product/dynamicAttrs/STRING_COL_1
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_2
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_3
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_4
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_5
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_6
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_7
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_8
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_9
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_10
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_11
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_12
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_13
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_14
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_15
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_16
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_17
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_18
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_19
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_20
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_21
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_22
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_23
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_24
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_25
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_26
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_27
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_28
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_29
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_30
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]

  - name: Product/dynamicAttrs/NUM_COL_1
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/NUM_COL_2
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/NUM_COL_3
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/NUM_COL_4
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/NUM_COL_5
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/NUM_COL_6
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/NUM_COL_7
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/NUM_COL_8
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/NUM_COL_9
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/NUM_COL_10
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]

  - name: Product/dynamicAttrs/DATE_COL_1
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
    ## End Product Dynamic Attrs

    ### End Product Fields

    # UI Resource for access to POS tab
  - name: SalesTab
    actions: [VIEW, UPDATE]

    ### Begin POS Fields

  - name: Sales
    group: sales
    actions: [VIEW, UPDATE]

  - name: Sales/sid
    group: sales
    actions: [VIEW]

  - name: Sales/createDate
    group: sales
    actions: [VIEW]

  - name: Sales/updateDate
    group: sales
    actions: [VIEW]

  - name: Sales/customerSid
    group: sales-internal
    actions: [VIEW]

  - name: Sales/deleted
    group: sales-internal
    actions: [VIEW]

  - name: Sales/branchId
    group: sales
    actions: [VIEW]

  - name: Sales/invoiceNumber
    group: sales
    actions: [VIEW]

  - name: Sales/invoiceDate
    group: sales
    actions: [VIEW]

  - name: Sales/quantity
    group: sales
    actions: [VIEW]

  - name: Sales/reportedSku
    group: sales
    actions: [VIEW, UPDATE]

  - name: Sales/productDescription
    group: sales
    actions: [VIEW]

  - name: Sales/transactionId
    group: sales-internal
    actions: [VIEW]

  - name: Sales/vendorPartNumber
    group: sales
    actions: [VIEW]

  - name: Sales/accountRepresentative
    group: sales
    actions: [VIEW]

  - name: Sales/acquisitionExtendedPrice
    group: sales
    actions: [VIEW]

  - name: Sales/acquisitionUnitPrice
    group: sales
    actions: [VIEW]

  - name: Sales/boolExtendedPrice
    group: sales
    actions: [VIEW]

  - name: Sales/bookUnitPrice
    group: sales
    actions: [VIEW]

  - name: Sales/customerOrderNumber
    group: sales
    actions: [VIEW]

  - name: Sales/debitExtendedPrice
    group: sales
    actions: [VIEW]

  - name: Sales/debitUnitPrice
    group: sales
    actions: [VIEW]

  - name: Sales/designRegistrationNumber
    group: sales
    actions: [VIEW]

  - name: Sales/distributorId
    group: sales
    actions: [VIEW]

  - name: Sales/distributorName
    group: sales
    actions: [VIEW]

  - name: Sales/distributorShipmentNumber
    group: sales
    actions: [VIEW]

  - name: Sales/distributorWarehouseId
    group: sales
    actions: [VIEW]

  - name: Sales/exchangeDate
    group: sales
    actions: [VIEW]

  - name: Sales/exchangeRate
    group: sales
    actions: [VIEW]

  - name: Sales/globalProductClassCode
    group: sales
    actions: [VIEW]

  - name: Sales/legacySalesRecordId
    group: sales
    actions: [VIEW]

  - name: Sales/lengthOfProduction
    group: sales
    actions: [VIEW]

  - name: Sales/manufactureId
    group: sales
    actions: [VIEW]

  - name: Sales/manufactureName
    group: sales
    actions: [VIEW]

  - name: Sales/manufacturerShipmentNumber
    group: sales
    actions: [VIEW]

  - name: Sales/orderNumber
    group: sales
    actions: [VIEW]

  - name: Sales/originalId
    group: sales
    actions: [VIEW]

  - name: Sales/price
    group: sales
    actions: [VIEW]

  - name: Sales/purchaseOrderNumber
    group: sales
    actions: [VIEW]

  - name: Sales/r2rDuplicateType
    group: sales
    actions: [VIEW]

  - name: Sales/regionTerritory
    group: sales
    actions: [VIEW]

  - name: Sales/reportEndingDate
    group: sales
    actions: [VIEW]

  - name: Sales/reportType
    group: sales
    actions: [VIEW]

  - name: Sales/resaleExtendedPrice
    group: sales
    actions: [VIEW]

  - name: Sales/resaeExtension
    group: sales
    actions: [VIEW]

  - name: Sales/resaleUnitPrice
    group: sales
    actions: [VIEW]

  - name: Sales/resubmitted
    group: sales
    actions: [VIEW]

  - name: Sales/reportedProductFamily
    group: sales
    actions: [VIEW]

  - name: Sales/reportedProductLine
    group: sales
    actions: [VIEW]

  - name: Sales/reportedProductName
    group: sales
    actions: [VIEW]

  - name: Sales/shipDate
    group: sales
    actions: [VIEW]

  - name: Sales/shipDebitNumber
    group: sales
    actions: [VIEW]

  - name: Sales/shippingMethod
    group: sales
    actions: [VIEW]

  - name: Sales/spaNumber
    group: sales
    actions: [VIEW]

  - name: Sales/tier
    group: sales
    actions: [VIEW]

  - name: Sales/transactionType
    group: sales
    actions: [VIEW]

  - name: Sales/unitOfMeasure
    group: sales
    actions: [VIEW]

  - name: Sales/vendorPartDescription
    group: sales
    actions: [VIEW]

  - name: Sales/validationCodes
    group: sales
    actions: [VIEW]

  - name: Sales/serialNumbers
    group: sales
    actions: [VIEW]

    # Bill to address


  - name: Sales/billToAddress
    group: sales-bill-to
    actions: [VIEW]

  - name: Sales/billToAddress/*
    group: sales-internal
    actions: [VIEW]

  - name: Sales/billToAddress/entityName
    group: sales-bill-to
    actions: [VIEW]

  - name: Sales/billToAddress/street1
    group: sales-bill-to
    actions: [VIEW]

  - name: Sales/billToAddress/street2
    group: sales-bill-to
    actions: [VIEW]

  - name: Sales/billToAddress/city
    group: sales-bill-to
    actions: [VIEW]

  - name: Sales/billToAddress/stateProvince
    group: sales-bill-to
    actions: [VIEW]

  - name: Sales/billToAddress/postalCode
    group: sales-bill-to
    actions: [VIEW]

  - name: Sales/billToAddress/reportedCountry
    group: sales-bill-to
    actions: [VIEW]

  - name: Sales/billToAddress/country
    group: sales-bill-to
    actions: [VIEW]

  - name: Sales/billToAddress/country/name
    group: sales-bill-to
    actions: [VIEW]

  - name: Sales/billToAddress/country/twoCharCode
    group: sales-bill-to
    actions: [VIEW]

  - name: Sales/billToAddress/country/threeCharCode
    group: sales-bill-to
    actions: [VIEW]

  - name: Sales/billToAddressExternalId
    group: sales-bill-to
    actions: [VIEW]

    # sold to address

  - name: Sales/soldToAddress
    group: sales-sold-to
    actions: [VIEW]

  - name: Sales/soldToAddress/*
    group: sales-internal
    actions: [VIEW]

  - name: Sales/soldToAddress/entityName
    group: sales-sold-to
    actions: [VIEW]

  - name: Sales/soldToAddress/street1
    group: sales-sold-to
    actions: [VIEW]

  - name: Sales/soldToAddress/street2
    group: sales-sold-to
    actions: [VIEW]

  - name: Sales/soldToAddress/city
    group: sales-sold-to
    actions: [VIEW]

  - name: Sales/soldToAddress/stateProvince
    group: sales-sold-to
    actions: [VIEW]

  - name: Sales/soldToAddress/postalCode
    group: sales-sold-to
    actions: [VIEW]

  - name: Sales/soldToAddress/reportedCountry
    group: sales-sold-to
    actions: [VIEW]

  - name: Sales/soldToAddress/country
    group: sales-sold-to
    actions: [VIEW]

  - name: Sales/soldToAddress/country/name
    group: sales-sold-to
    actions: [VIEW]

  - name: Sales/soldToAddress/country/twoCharCode
    group: sales-sold-to
    actions: [VIEW]

  - name: Sales/soldToAddress/country/threeCharCode
    group: sales-sold-to
    actions: [VIEW]

  - name: Sales/soldToAddressExternalId
    group: sales-sold-to
    actions: [VIEW]

    # ship to address

  - name: Sales/shipToAddress
    group: sales-ship-to
    actions: [VIEW]

  - name: Sales/shipToAddress/*
    group: sales-internal
    actions: [VIEW]

  - name: Sales/shipToAddress/entityName
    group: sales-ship-to
    actions: [VIEW]

  - name: Sales/shipToAddress/street1
    group: sales-ship-to
    actions: [VIEW]

  - name: Sales/shipToAddress/street2
    group: sales-ship-to
    actions: [VIEW]

  - name: Sales/shipToAddress/city
    group: sales-ship-to
    actions: [VIEW]

  - name: Sales/shipToAddress/stateProvince
    group: sales-ship-to
    actions: [VIEW]

  - name: Sales/shipToAddress/postalCode
    group: sales-ship-to
    actions: [VIEW]

  - name: Sales/shipToAddress/reportedCountry
    group: sales-ship-to
    actions: [VIEW]

  - name: Sales/shipToAddress/country
    group: sales-ship-to
    actions: [VIEW]

  - name: Sales/shipToAddress/country/name
    group: sales-ship-to
    actions: [VIEW]

  - name: Sales/shipToAddress/country/twoCharCode
    group: sales-ship-to
    actions: [VIEW]

  - name: Sales/shipToAddress/country/threeCharCode
    group: sales-ship-to
    actions: [VIEW]

  - name: Sales/shipToAddressExternalId
    group: sales-ship-to
    actions: [VIEW]

    # sell from address

  - name: Sales/sellFromAddress
    group: sales-sell-from
    actions: [VIEW]

  - name: Sales/sellFromAddress/*
    group: sales-internal
    actions: [VIEW]

  - name: Sales/sellFromAddress/entityName
    group: sales-sell-from
    actions: [VIEW]

  - name: Sales/sellFromAddress/street1
    group: sales-sell-from
    actions: [VIEW]

  - name: Sales/sellFromAddress/street2
    group: sales-sell-from
    actions: [VIEW]

  - name: Sales/sellFromAddress/city
    group: sales-sell-from
    actions: [VIEW]

  - name: Sales/sellFromAddress/stateProvince
    group: sales-sell-from
    actions: [VIEW]

  - name: Sales/sellFromAddress/postalCode
    group: sales-sell-from
    actions: [VIEW]

  - name: Sales/sellFromAddress/reportedCountry
    group: sales-sell-from
    actions: [VIEW]

  - name: Sales/sellFromAddress/country
    group: sales-sell-from
    actions: [VIEW]

  - name: Sales/sellFromAddress/country/name
    group: sales-sell-from
    actions: [VIEW]

  - name: Sales/sellFromAddress/country/twoCharCode
    group: sales-sell-from
    actions: [VIEW]

  - name: Sales/sellFromAddress/country/threeCharCode
    group: sales-sell-from
    actions: [VIEW]

  - name: Sales/sellFromAddressExternalId
    group: sales-sell-from
    actions: [VIEW]

    # ship from address

  - name: Sales/shipFromAddress
    group: sales-ship-from
    actions: [VIEW]

  - name: Sales/shipFromAddress/*
    group: sales-internal
    actions: [VIEW]

  - name: Sales/shipFromAddress/entityName
    group: sales-ship-from
    actions: [VIEW]

  - name: Sales/shipFromAddress/street1
    group: sales-ship-from
    actions: [VIEW]

  - name: Sales/shipFromAddress/street2
    group: sales-ship-from
    actions: [VIEW]

  - name: Sales/shipFromAddress/city
    group: sales-ship-from
    actions: [VIEW]

  - name: Sales/shipFromAddress/stateProvince
    group: sales-ship-from
    actions: [VIEW]

  - name: Sales/shipFromAddress/postalCode
    group: sales-ship-from
    actions: [VIEW]

  - name: Sales/shipFromAddress/reportedCountry
    group: sales-ship-from
    actions: [VIEW]

  - name: Sales/shipFromAddress/country
    group: sales-ship-from
    actions: [VIEW]

  - name: Sales/shipFromAddress/country/name
    group: sales-ship-from
    actions: [VIEW]

  - name: Sales/shipFromAddress/country/twoCharCode
    group: sales-ship-from
    actions: [VIEW]

  - name: Sales/shipFromAddress/country/threeCharCode
    group: sales-ship-from
    actions: [VIEW]

  - name: Sales/shipFromAddressExternalId
    group: sales-ship-from
    actions: [VIEW]

    # sales in address

  - name: Sales/salesInAddress
    group: sales-sales-in
    actions: [VIEW]

  - name: Sales/salesInAddress/*
    group: sales-internal
    actions: [VIEW]

  - name: Sales/salesInAddress/entityName
    group: sales-sales-in
    actions: [VIEW]

  - name: Sales/salesInAddress/street1
    group: sales-sales-in
    actions: [VIEW]

  - name: Sales/salesInAddress/street2
    group: sales-sales-in
    actions: [VIEW]

  - name: Sales/salesInAddress/city
    group: sales-sales-in
    actions: [VIEW]

  - name: Sales/salesInAddress/stateProvince
    group: sales-sales-in
    actions: [VIEW]

  - name: Sales/salesInAddress/postalCode
    group: sales-sales-in
    actions: [VIEW]

  - name: Sales/salesInAddress/reportedCountry
    group: sales-sales-in
    actions: [VIEW]

  - name: Sales/salesInAddress/country
    group: sales-sales-in
    actions: [VIEW]

  - name: Sales/salesInAddress/country/name
    group: sales-sales-in
    actions: [VIEW]

  - name: Sales/salesInAddress/country/twoCharCode
    group: sales-sales-in
    actions: [VIEW]

  - name: Sales/salesInAddress/country/threeCharCode
    group: sales-sales-in
    actions: [VIEW]

  - name: Sales/salesInAddressExternalId
    group: sales-sales-in
    actions: [VIEW]

    # purchasing customer address

  - name: Sales/purchasingCustomerAddress
    group: sales-purchasing-customer
    actions: [VIEW]

  - name: Sales/purchasingCustomerAddress/*
    group: sales-internal
    actions: [VIEW]

  - name: Sales/purchasingCustomerAddress/entityName
    group: sales-purchasing-customer
    actions: [VIEW]

  - name: Sales/purchasingCustomerAddress/street1
    group: sales-purchasing-customer
    actions: [VIEW]

  - name: Sales/purchasingCustomerAddress/street2
    group: sales-purchasing-customer
    actions: [VIEW]

  - name: Sales/purchasingCustomerAddress/city
    group: sales-purchasing-customer
    actions: [VIEW]

  - name: Sales/purchasingCustomerAddress/stateProvince
    group: sales-purchasing-customer
    actions: [VIEW]

  - name: Sales/purchasingCustomerAddress/postalCode
    group: sales-purchasing-customer
    actions: [VIEW]

  - name: Sales/purchasingCustomerAddress/reportedCountry
    group: sales-purchasing-customer
    actions: [VIEW]

  - name: Sales/purchasingCustomerAddress/country
    group: sales-purchasing-customer
    actions: [VIEW]

  - name: Sales/purchasingCustomerAddress/country/name
    group: sales-purchasing-customer
    actions: [VIEW]

  - name: Sales/purchasingCustomerAddress/country/twoCharCode
    group: sales-purchasing-customer
    actions: [VIEW]

  - name: Sales/purchasingCustomerAddress/country/threeCharCode
    group: sales-purchasing-customer
    actions: [VIEW]

  - name: Sales/purchasingCustomerExternalId
    group: sales-purchasing-customer
    actions: [VIEW]

    # derived end customer address

  - name: Sales/derivedEndCustomerAddress
    group: sales-derived-end-customer
    actions: [VIEW]

  - name: Sales/derivedEndCustomerAddress/*
    group: sales-internal
    actions: [VIEW]

  - name: Sales/derivedEndCustomerAddress/entityName
    group: sales-derived-end-customer
    actions: [VIEW]

  - name: Sales/derivedEndCustomerAddress/street1
    group: sales-derived-end-customer
    actions: [VIEW]

  - name: Sales/derivedEndCustomerAddress/street2
    group: sales-derived-end-customer
    actions: [VIEW]

  - name: Sales/derivedEndCustomerAddress/city
    group: sales-derived-end-customer
    actions: [VIEW]

  - name: Sales/derivedEndCustomerAddress/stateProvince
    group: sales-derived-end-customer
    actions: [VIEW]

  - name: Sales/derivedEndCustomerAddress/postalCode
    group: sales-derived-end-customer
    actions: [VIEW]

  - name: Sales/derivedEndCustomerAddress/reportedCountry
    group: sales-derived-end-customer
    actions: [VIEW]

  - name: Sales/derivedEndCustomerAddress/country
    group: sales-derived-end-customer
    actions: [VIEW]

  - name: Sales/derivedEndCustomerAddress/country/name
    group: sales-derived-end-customer
    actions: [VIEW]

  - name: Sales/derivedEndCustomerAddress/country/twoCharCode
    group: sales-derived-end-customer
    actions: [VIEW]

  - name: Sales/derivedEndCustomerAddress/country/threeCharCode
    group: sales-derived-end-customer
    actions: [VIEW]

  - name: Sales/derivedEndCustomerAddressExternalId
    group: sales-derived-end-customer
    actions: [VIEW]

    # data file

  - name: Sales/dataFile
    group: sales-data-file
    actions: [VIEW]

  - name: Sales/dataFile/*
    group: sales-internal
    actions: [VIEW]

  - name: Sales/dataFile/loadDate
    group: sales-data-file
    actions: [VIEW]

  - name: Sales/dataFile/reportDate
    group: sales-data-file
    actions: [VIEW]

  - name: Sales/dataFile/id
    group: sales-data-file
    actions: [VIEW]

  - name: Sales/dataFile/fileName
    group: sales-data-file
    actions: [VIEW]

  - name: Sales/dataFile/recordCount
    group: sales-data-file
    actions: [VIEW]

    # match info

  - name: Sales/productMatchInfo
    group: sales-product-match-info
    actions: [VIEW]

  - name: Sales/productMatchInfo/*
    group: sales-internal
    actions: [VIEW]

  - name: Sales/productMatchInfo/matchedProduct
    group: sales-product-match-info
    actions: [VIEW]

  - name: Sales/productMatchInfo/matchedProduct/sku
    group: sales-product-match-info
    actions: [VIEW]

    # reporting partner

  - name: Sales/reportingPartner
    group: sales-reporting-partner
    actions: [VIEW]

  - name: Sales/reportingPartner/*
    group: sales-internal
    actions: [VIEW]

  - name: Sales/reportingPartner/gsNumbers
    group: sales-reporting-partner
    actions: [VIEW]

  - name: Sales/reportingPartner/gsNumbers/value
    group: sales-reporting-partner
    actions: [VIEW]

    # currency

  - name: Sales/currency
    group: sales-currency
    actions: [VIEW]

  - name: Sales/currency/*
    group: sales-internal
    actions: [VIEW]

  - name: Sales/currency/name
    group: sales-currency
    actions: [VIEW]

    # resale currency

  - name: Sales/resaleCurrency
    group: sales-resale-currency
    actions: [VIEW]

  - name: Sales/resaleCurrency/*
    group: sales-internal
    actions: [VIEW]

  - name: Sales/resaleCurrency/name
    group: sales-resale-currency
    actions: [VIEW]

    # debit currency

  - name: Sales/debtCurrency
    group: sales-debit-currency
    actions: [VIEW]

  - name: Sales/debtCurrency/*
    group: sales-internal
    actions: [VIEW]

  - name: Sales/debtCurrency/name
    group: sales-debit-currency
    actions: [VIEW]

    # book currency

  - name: Sales/bookCurrency
    group: sales-book-currency
    actions: [VIEW]

  - name: Sales/bookCurrency/*
    group: sales-internal
    actions: [VIEW]

  - name: Sales/bookCurrency/name
    group: sales-book-currency
    actions: [VIEW]

    # acquisition currency

  - name: Sales/acquisitionCurrency
    group: sales-acquisition-currency
    actions: [VIEW]

  - name: Sales/acquisitionCurrency/*
    group: sales-internal
    actions: [VIEW]

  - name: Sales/acquisitionCurrency/name
    group: sales-acquisition-currency
    actions: [VIEW]

    ## Begin POS Dynamic Attrs

  - name: Sales/dynamicAttrs
    group: sales-dynamic-attrs
    actions: [VIEW, UPDATE]

  - name: Sales/dynamicAttrs/*
    group: sales-dynamic-attrs
    actions: [VIEW, UPDATE]

  - name: Sales/dynamicAttrs/STRING_COL_1
    group: sales-dynamic-attrs
    actions: [VIEW, UPDATE]

    ## End POS Dynamic Attrs

    ### End POS Fields

    # UI Resource for access to INV tab
  - name: InventoryTab
    actions: [VIEW, UPDATE]

    ### Begin INV Fields

  - name: Inventory
    group: inventory
    actions: [VIEW, UPDATE]

  - name: Inventory/sid
    group: inventory
    actions: [VIEW]

  - name: Inventory/createDate
    group: inventory
    actions: [VIEW]

  - name: Inventory/updateDate
    group: inventory
    actions: [VIEW]

  - name: Inventory/customerSid
    group: inventory-internal
    actions: [VIEW]

  - name: Inventory/deleted
    group: inventory-internal
    actions: [VIEW]

  - name: Inventory/productName
    group: inventory
    actions: [VIEW]

  - name: Inventory/clientDescription
    group: inventory
    actions: [VIEW]

  - name: Inventory/clientSku
    group: inventory
    actions: [VIEW, UPDATE]

  - name: Inventory/reportedSku
    group: inventory
    actions: [VIEW]

  - name: Inventory/inventoryDate
    group: inventory
    actions: [VIEW]

  - name: Inventory/unitOfMeasure
    group: inventory
    actions: [VIEW]

  - name: Inventory/id
    group: inventory-internal
    actions: [VIEW]

  - name: Inventory/originalId
    group: inventory
    actions: [VIEW]

  - name: Inventory/lineNumber
    group: inventory-internal
    actions: [VIEW]

    # data file

  - name: Inventory/dataFile
    group: inventory-data-file
    actions: [VIEW]

  - name: Inventory/dataFile/*
    group: inventory-internal
    actions: [VIEW]

  - name: Inventory/dataFile/loadDate
    group: inventory-data-file
    actions: [VIEW]

  - name: Inventory/dataFile/reportDate
    group: inventory-data-file
    actions: [VIEW]

  - name: Inventory/dataFile/id
    group: inventory-data-file
    actions: [VIEW]

  - name: Inventory/dataFile/fileName
    group: inventory-data-file
    actions: [VIEW]

  - name: Inventory/dataFile/recordCount
    group: inventory-data-file
    actions: [VIEW]

    # reporting partner

  - name: Inventory/reportingPartner
    group: inventory-reporting-partner
    actions: [VIEW]

  - name: Inventory/reportingPartner/*
    group: inventory-internal
    actions: [VIEW]

  - name: Inventory/reportingPartner/gsNumbers
    group: inventory-reporting-partner
    actions: [VIEW]

  - name: Inventory/reportingPartner/gsNumbers/value
    group: inventory-reporting-partner
    actions: [VIEW]

    # submission period

  - name: Inventory/submissionPeriod
    group: inventory-submission-period
    actions: [VIEW]

  - name: Inventory/submissionPeriod/*
    group: inventory-internal
    actions: [VIEW]

  - name: Inventory/submissionPeriod/expectedDate
    group: inventory-submission-period
    actions: [VIEW]

  - name: Inventory/submissionPeriod/periodStartDate
    group: inventory-submission-period
    actions: [VIEW]

  - name: Inventory/submissionPeriod/periodEndDate
    group: inventory-submission-period
    actions: [VIEW]

    # quantities

  - name: Inventory/inventoryQuantities
    group: inventory-quantity
    actions: [VIEW]

  - name: Inventory/inventoryQuantities/*
    group: inventory-internal
    actions: [VIEW]

  - name: Inventory/onHandQuantity
    group: inventory-quantity
    actions: [VIEW]

  - name: Inventory/onHandQuantity/*
    group: inventory-internal
    actions: [VIEW]

  - name: Inventory/onHandQuantity/value
    group: inventory-quantity
    actions: [VIEW]

  - name: Inventory/onOrderQuantity
    group: inventory-quantity
    actions: [VIEW]

  - name: Inventory/onOrderQuantity/*
    group: inventory-internal
    actions: [VIEW]

  - name: Inventory/onOrderQuantity/value
    group: inventory-quantity
    actions: [VIEW]

  - name: Inventory/committedQuantity
    group: inventory-quantity
    actions: [VIEW]

  - name: Inventory/committedQuantity/*
    group: inventory-internal
    actions: [VIEW]

  - name: Inventory/committedQuantity/value
    group: inventory-quantity
    actions: [VIEW]

  - name: Inventory/floatQuantity
    group: inventory-quantity
    actions: [VIEW]

  - name: Inventory/floatQuantity/*
    group: inventory-internal
    actions: [VIEW]

  - name: Inventory/floatQuantity/value
    group: inventory-quantity
    actions: [VIEW]

  - name: Inventory/backorderedQuantity
    group: inventory-quantity
    actions: [VIEW]

  - name: Inventory/backorderedQuantity/*
    group: inventory-internal
    actions: [VIEW]

  - name: Inventory/backorderedQuantity/value
    group: inventory-quantity
    actions: [VIEW]

  - name: Inventory/returnedQuantity
    group: inventory-quantity
    actions: [VIEW]

  - name: Inventory/returnedQuantity/*
    group: inventory-internal
    actions: [VIEW]

  - name: Inventory/returnedQuantity/value
    group: inventory-quantity
    actions: [VIEW]

  - name: Inventory/inTransitQuantity
    group: inventory-quantity
    actions: [VIEW]

  - name: Inventory/inTransitQuantity/*
    group: inventory-internal
    actions: [VIEW]

  - name: Inventory/inTransitQuantity/value
    group: inventory-quantity
    actions: [VIEW]

    # prices

  - name: Inventory/inventoryPrices
    group: inventory-price
    actions: [VIEW]

  - name: Inventory/inventoryPrices/*
    group: inventory-internal
    actions: [VIEW]

  - name: Inventory/unitPrice
    group: inventory-price
    actions: [VIEW]

  - name: Inventory/unitPrice/*
    group: inventory-internal
    actions: [VIEW]

  - name: Inventory/unitPrice/price
    group: inventory-price
    actions: [VIEW]

  - name: Inventory/unitPrice/fromCurrency
    group: inventory-price
    actions: [VIEW]

  - name: Inventory/unitPrice/fromCurrency/name
    group: inventory-price
    actions: [VIEW]

  - name: Inventory/unitPrice/toCurrency
    group: inventory-price
    actions: [VIEW]

  - name: Inventory/unitPrice/toCurrency/name
    group: inventory-price
    actions: [VIEW]

    ## Begin INV Dynamic Attrs

  - name: Inventory/dynamicAttrs
    group: inventory-dynamic-attrs
    actions: [VIEW]

  - name: Inventory/dynamicAttrs/*
    group: inventory-dynamic-attrs
    actions: [VIEW]

    ## End INV Dynamic Attrs

    ### End INV Fields

  # UI Resource for access to File Tab
  - name: FilesTab
    actions: [VIEW, UPDATE]

  ## Begin Partner

  - name: Partner
    group: reporting-partner
    actions: [VIEW]

  - name: Partner/*
    group: reporting-partner
    actions: [VIEW]

  ## End Partner

  # Begin File fields
  - name: DataFile
    group: file-management
    actions: [VIEW, UPDATE]

  - name: DataFile/sid
    group: file-management
    actions: [VIEW]

  - name: DataFile/loadDate
    group: file-management
    actions: [VIEW]

  - name: DataFile/reportDate
    group: file-management
    actions: [VIEW]

  - name: DataFile/fileName
    group: file-management
    actions: [VIEW]

  - name: DataFile/fileType
    group: file-management
    actions: [VIEW]

  - name: DataFile/dataType
    group: file-management
    actions: [VIEW]

  - name: DataFile/id
    group: file-management
    actions: [VIEW]

  - name: DataFile/fileSize
    group: file-management
    actions: [VIEW]

  - name: DataFile/source
    group: file-management
    actions: [VIEW]

  - name: DataFile/recordCount
    group: file-management
    actions: [VIEW]

  - name: DataFile/deletedLines
    group: file-management
    actions: [VIEW]

  - name: DataFile/download
    group: file-download
    actions: [VIEW]

  - name: DataFile/validationDownload
    group: file-validation-download
    actions: [VIEW]

  - name: DataFile/upload
    group: file-upload
    actions: [VIEW]

  - name: DataFile/uploadDataTypes
    group: file-upload
    actions: [VIEW]

  - name: DataFile/uploadFileTypes
    group: file-upload
    actions: [VIEW]

  - name: DataFile/reportingPartner
    group: file-reporting-partner
    actions: [VIEW]

  - name: DataFile/reportingPartner/*
    group: file-reporting-partner
    actions: [VIEW]

  - name: DataFile/reportingPartner/partnerOverlayView
    group: file-reporting-partner
    actions: [VIEW]

  - name: DataFile/reportingPartner/partnerOverlayView/*
    group: file-reporting-partner
    actions: [VIEW]

  - name: DataFile/dataFileState
    group: file-data-file-state
    actions: [VIEW]

  - name: DataFile/dataFileState/*
    group: file-data-file-state
    actions: [VIEW]

  - name: DataFile/dataFileState/sid
    group: file-data-file-state
    actions: [VIEW]

  - name: DataFile/dataFileState/createDate
    group: file-data-file-state
    actions: [VIEW]

  - name: DataFile/dataFileState/updateDate
    group: file-data-file-state
    actions: [VIEW]

  - name: DataFile/parserAttempt
    group: file-parser-attempt
    actions: [VIEW]

  - name: DataFile/parserAttempt/*
    group: file-parser-attempt
    actions: [VIEW]

  # End of File fields
  
  # UI Resource for access to Submission Schedule
  - name: SubmissionTrackingTab
    actions: [VIEW, UPDATE]

  - name: SubmissionResultsTab
    actions: [VIEW, UPDATE]

  # Begin Submission Schedule 
  - name: SubmissionSchedule
    group: submission-schedule
    actions: [VIEW, UPDATE]

  - name: SubmissionSchedule/sid
    group: submission-schedule
    actions: [VIEW]

  - name: SubmissionSchedule/createDate
    group: submission-schedule
    actions: [VIEW]

  - name: SubmissionSchedule/updateDate
    group: submission-schedule
    actions: [VIEW]

  - name: SubmissionSchedule/name
    group: submission-schedule
    actions: [VIEW]

  - name: SubmissionSchedule/reportingPartner
    group: ss-reporting-partner
    actions: [VIEW]

  - name: SubmissionSchedule/reportingPartner/*
    group: ss-reporting-partner
    actions: [VIEW]

  - name: SubmissionSchedule/reportingPartner/partnerOverlayView
    group: ss-reporting-partner
    actions: [VIEW]

  - name: SubmissionSchedule/reportingPartner/partnerOverlayView/*
    group: ss-reporting-partner
    actions: [VIEW]

  - name: SubmissionSchedule/dataType
    group: ss-data-type
    actions: [VIEW]

  - name: SubmissionSchedule/dataType/*
    group: ss-data-type
    actions: [VIEW]

  - name: SubmissionSchedule/periodRule
    group: submission-schedule
    actions: [VIEW]

  - name: SubmissionSchedule/expectedDay
    group: submission-schedule
    actions: [VIEW]

  - name: SubmissionSchedule/startDate
    group: submission-schedule
    actions: [VIEW]

  - name: SubmissionSchedule/endDate
    group: submission-schedule
    actions: [VIEW]

  - name: SubmissionSchedule/isInPeriodReporter
    group: submission-schedule
    actions: [VIEW]

  - name: SubmissionSchedule/weekOfMonth
    group: submission-schedule
    actions: [VIEW]

  - name: SubmissionSchedule/monthOfQuarter
    group: submission-schedule
    actions: [VIEW]

  - name: SubmissionSchedule/workingDays
    group: submission-schedule
    actions: [VIEW]

  # End Submission Schedule 

  # Begin Submission Schedule Notification
  - name: SubmissionScheduleNotification
    group: submission-schedule-notification
    actions: [VIEW]
  
  - name: SubmissionScheduleNotification/*
    group: submission-schedule-notification
    actions: [VIEW]

  - name: SubmissionScheduleNotification/notificationType
    group: submission-schedule-notification
    actions: [VIEW]

  - name: SubmissionScheduleNotification/notificationType/*
    group: submission-schedule-notification
    actions: [VIEW]

  - name: SubmissionScheduleNotification/serviceUser
    group: submission-schedule-notification
    actions: [VIEW]

  - name: SubmissionScheduleNotification/serviceUser/*
    group: submission-schedule-notification
    actions: [VIEW]

  # END Submission Schedule Notification

  # Begin Submission Period
  - name: SubmissionPeriod
    group: submission-period-update
    actions: [VIEW, UPDATE]

  - name: SubmissionPeriod/sid
    group: submission-period
    actions: [VIEW]

  - name: SubmissionPeriod/expectedDate
    group: submission-period
    actions: [VIEW]

  - name: SubmissionPeriod/periodStartDate
    group: submission-period
    actions: [VIEW]

  - name: SubmissionPeriod/periodEndDate
    group: submission-period
    actions: [VIEW]

  - name: SubmissionPeriod/createDate
    group: submission-period
    actions: [VIEW]

  - name: SubmissionPeriod/updateDate
    group: submission-period
    actions: [VIEW]

  - name: SubmissionPeriod/noData
    group: submission-period-update
    actions: [VIEW, UPDATE]

  - name: SubmissionPeriod/noDataReason
    group: submission-period-update
    actions: [VIEW, UPDATE]

  - name: SubmissionPeriod/noDataCreateDate
    group: submission-period-update
    actions: [VIEW, UPDATE]

  - name: SubmissionPeriod/onTimeOverride
    group: submission-period
    actions: [VIEW]

  - name: SubmissionPeriod/expectedDay
    group: submission-period
    actions: [VIEW]

  - name: SubmissionPeriod/workingDays
    group: submission-period
    actions: [VIEW]

  - name: SubmissionPeriod/isInPeriodReporter
    group: submission-period
    actions: [VIEW]

  - name: SubmissionPeriod/trackingLevel
    group: submission-period
    actions: [VIEW]

  - name: SubmissionPeriod/status
    group: submission-period
    actions: [VIEW]

  - name: SubmissionPeriod/reportedFlag
    group: submission-period
    actions: [VIEW]

  - name: SubmissionPeriod/fileIds
    group: submission-period
    actions: [VIEW]

  - name: SubmissionPeriod/firstFileName
    group: submission-period
    actions: [VIEW]

  - name: SubmissionPeriod/firstFileCreateDate
    group: submission-period
    actions: [VIEW]

  - name: SubmissionPeriod/firstFileId
    group: submission-period
    actions: [VIEW]

  - name: SubmissionPeriod/deleted
    group: submission-period
    actions: [VIEW]

  - name: SubmissionPeriod/noDataServiceUser
    group: submission-period-update
    actions: [VIEW, UPDATE]

  - name: SubmissionPeriod/noDataServiceUser/sid
    group: sp-no-data-user
    actions: [VIEW]

  - name: SubmissionPeriod/noDataServiceUser/firstName
    group: sp-no-data-user
    actions: [VIEW]

  - name: SubmissionPeriod/noDataServiceUser/lastName
    group: sp-no-data-user
    actions: [VIEW]

  - name: SubmissionPeriod/noDataServiceUser/email
    group: sp-no-data-user
    actions: [VIEW]

  - name: SubmissionPeriod/submissionPeriodLineItemView
    group: submission-period
    actions: [VIEW]

  - name: SubmissionPeriod/submissionPeriodLineItemView/*
    group: submission-period
    actions: [VIEW]

  - name: SubmissionPeriod/dataFileSummaryInfo
    group: submission-period
    actions: [VIEW]

  - name: SubmissionPeriod/dataFileSummaryInfo/*
    group: submission-period
    actions: [VIEW]
    
  - name: SubmissionPeriod/submissionSchedule
    group: submission-period
    actions: [VIEW]
    
  - name: SubmissionPeriod/submissionSchedule/sid
    group: submission-period
    actions: [VIEW]
    
  - name: SubmissionPeriod/submissionSchedule/name
    group: submission-period
    actions: [VIEW]
    
  - name: SubmissionPeriod/submissionSchedule/periodRule
    group: submission-period
    actions: [VIEW]

  - name: SubmissionPeriod/submissionSchedule/reportingPartner
    group: sp-reporting-partner
    actions: [VIEW]

  - name: SubmissionPeriod/submissionSchedule/reportingPartner/*
    group: sp-reporting-partner
    actions: [VIEW]

  - name: SubmissionPeriod/submissionSchedule/reportingPartner/partnerOverlayView
    group: sp-reporting-partner
    actions: [VIEW]

  - name: SubmissionPeriod/submissionSchedule/reportingPartner/partnerOverlayView/*
    group: sp-reporting-partner
    actions: [VIEW]

  - name: SubmissionPeriod/submissionSchedule/dataType
    group: sp-data-type
    actions: [VIEW]

  - name: SubmissionPeriod/submissionSchedule/dataType/*
    group: sp-data-type
    actions: [VIEW]

  # End Submission Period

  # Begin Export Request

  - name: ExportRequest
    group: export
    actions: [VIEW, UPDATE]

  - name: ExportRequest/*
    group: export
    actions: [VIEW, UPDATE]

  # End Export Request

  ### Begin Base resources

  - name: About
    group: about
    actions: [VIEW]

  - name: About/*
    group: about
    actions: [VIEW]

  - name: UserEvent
    group: user-event
    actions: [VIEW, UPDATE]

  - name: UserEvent/*
    group: user-event
    actions: [VIEW, UPDATE]

  - name: ObjectLock
    group: object-lock
    actions: [VIEW, UPDATE]

  - name: ObjectLock/*
    group: object-lock
    actions: [VIEW, UPDATE]

  - name: ObjectLockResponse
    group: object-lock-response
    actions: [VIEW]

  - name: ObjectLockResponse/*
    group: object-lock-response
    actions: [VIEW]

  - name: MutationResponse
    group: mutation-response
    actions: [VIEW]

  - name: MutationResponse/*
    group: mutation-response
    actions: [VIEW]

  - name: DynamicAttrMetadata
    group: attr-metadata
    actions: [VIEW]

  - name: DynamicAttrMetadata/*
    group: attr-metadata
    actions: [VIEW]
    

  ### End Base resources

  ### Begin mutation resources

  - name: Product/mutation/*
    group: product-update
    actions: [UPDATE]

  - name: Sales/mutation/*
    group: sales-update
    actions: [UPDATE]

  - name: Inventory/mutation/*
    group: inventory-update
    actions: [UPDATE]

  - name: ExportRequest/mutation/*
    group: export
    actions: [UPDATE]

  - name: SubmissionPeriod/mutation/*
    group: submission-period-mutation
    actions: [UPDATE]

    ### End mutation resources

    ### Begin Customer Resources

  - name: INT
    actions: [VIEW]

  - name: ACS
    actions: [VIEW]

  - name: CAMB
    actions: [VIEW]

  - name: CYBERDYNE
    actions: [VIEW]

  - name: COR
    actions: [VIEW]

  - name: INT_CCD
    actions: [VIEW]

  - name: ACS_CCD
    actions: [VIEW]

  - name: CAMB_CCD
    actions: [VIEW]

  - name: QCOM_CCD
    actions: [VIEW]

  - name: COR_CCD
    actions: [VIEW]

    ### End Customer Resources

# Common permissions for all tenants
permissions:

  - name: BasicViewUpdate
    displayName: Background Permissions
    description: Every User needs this permission
    resource-actions:
      - about:[VIEW]
      - user-event:[VIEW, UPDATE]
      - object-lock:[VIEW, UPDATE]
      - object-lock-response:[VIEW]
      - mutation-response:[VIEW]
      - attr-metadata:[VIEW]

  - name: KpiView
    displayName: KPI Tab
    description: KPI Permission Set
    resource-actions:
      - ProductKpiTab:[VIEW]

  - name: SSKpiFields
    displayName: Submission KPI Fields
    description: Submission KPI Fields Permission Set
    resource-actions:
      - ssKpi:[VIEW]

  - name: FilesKpiFields
    displayName: Files KPI Fields
    description: Files KPI Fields Permission Set
    resource-actions:
      - filesKpi:[VIEW]

  - name: FileTab
    displayName: File Tab
    description: File Permission Set
    resource-actions:
      - FilesTab:[VIEW]

  - name: FileUploadPartner
    displayName: File Upload for Partner
    description: File Upload Permission Set
    resource-actions:
      - DataFile:[VIEW, UPDATE] 
      - file-upload:[VIEW]     

  - name: FileUpload
    displayName: File Upload 
    description: File Upload Permission Set
    resource-actions:
      - DataFile:[VIEW]
      - file-upload:[VIEW]
      - reporting-partner:[VIEW]

  - name: FileDownload
    displayName: File Download
    description: File Download Permission Set
    resource-actions:
      - DataFile:[VIEW]
      - file-download:[VIEW]
      - file-validation-download:[VIEW]

  - name: SubmissionTab
    displayName: Submission Tab
    description: File Permission Set
    resource-actions:
      - SubmissionTrackingTab:[VIEW]
      - SubmissionResultsTab:[VIEW]

  - name: FileManufactureView
    displayName: File Admin View
    description: File Admin Permission Set
    resource-actions:
      - file-management:[VIEW]
      - file-reporting-partner:[VIEW]
      - file-data-file-state:[VIEW]
      - file-parser-attempt:[VIEW]

  - name: FilePartnerView
    displayName: File Partner View
    description: File Partner Permission Set
    resource-actions:
      - file-management:[VIEW]
      - file-data-file-state:[VIEW]
      - file-parser-attempt:[VIEW]

  - name: SubmissionManufactureView
    displayName: Submission Admin View
    description: Submission Full Permission Set
    resource-actions:
      - submission-schedule:[VIEW]
      - submission-schedule-notification:[VIEW]
      - ss-reporting-partner:[VIEW]
      - ss-data-type:[VIEW]
      - submission-period:[VIEW]
      - sp-reporting-partner:[VIEW]
      - sp-data-type:[VIEW]
      - sp-no-data-user:[VIEW]
      - submission-period-update:[VIEW]

  - name: SubmissionPartnerView
    displayName: Submission Partner View
    description: Submission Full Permission Set
    resource-actions:
      - submission-schedule:[VIEW]
      - submission-schedule-notification:[VIEW]
      - ss-data-type:[VIEW]
      - submission-period:[VIEW]
      - sp-data-type:[VIEW]
      - sp-no-data-user:[VIEW]
      - submission-period-update:[VIEW]

  - name: SubmissionPartnerUpdate
    displayName: Submission Partner Update
    description: Submission Update Permission Set
    resource-actions:
      - submission-period-update:[UPDATE]
      - submission-period-mutation:[UPDATE]

  - name: SubmissionUpdate
    displayName: Submission Update 
    description: Submission Update Permission Set
    resource-actions:
      - submission-period-update:[UPDATE]
      - submission-period-mutation:[UPDATE]
export const SubmissionDef = `
  type Query {
    submissionPeriods(
      offset: Float, 
      limit: Float,
      filters: SubmissionPeriodFilters,
      sort: SubmissionPeriodSort
    ): [SubmissionPeriod]
    submissionSchedules(
      offset: Float, 
      limit: Float,
      filters: SubmissionScheduleFilters, 
      sort: SubmissionScheduleSort
    ): [SubmissionSchedule]
    submissionScheduleNotifications(
      submissionScheduleSid: ID,
      offset: Float,
      limit: Float,
      filters: SubmissionScheduleNotificationFilters,
      sort: SubmissionScheduleNotificationSort
    ): [SubmissionScheduleNotification]
  }

  type Mutation {
    markNoData(data: [NoDataInput]): [MutationResponse] @auth(object: SubmissionPeriod)
  }

  type SubmissionPeriod {
    sid: ID
    createDate: Date
    updateDate: Date
    customerSid: ID
    expectedDate: Date
    periodStartDate: Date
    periodEndDate: Date
    noData: Boolean
    noDataReason: String
    noDataCreateDate: Date
    onTimeOverride: Boolean
    expectedDay: String
    workingDays: String
    isInPeriodReporter: Float
    trackingLevel: String
    submissionSchedule: SubmissionSchedule
    status: String
    reportedFlag: Boolean
    numberOfFiles: Float
    dataFileSummaryInfo: [DataFileSummaryInfo]
    submissionPeriodInfoView: SubmissionPeriodInfoView
    submissionPeriodLineItemView: SubmissionPeriodLineItemView
    noDataServiceUser: ServiceUser
  }

  type SubmissionPeriodLineItemView {
    salesLineItemCount: Float
    invLineItemCount: Float
    earliestFileSubmissionDate: Date
  }

  type SubmissionPeriodInfoView {
    numberOfInventoryLines: Float
    numberOfPOSLines:Float
    fileName: String
    fileId: Float
  }

  type DataFileSummaryInfo{
    numberOfPOSLines: Float
    numberOfInventoryLines: Float
    receivedDate: Date
    dataFileId: String
    dataFileName: String
  }
  
  type SubmissionSchedule {
    sid: ID
    createDate: Date
    updateDate: Date
    customerSid: ID
    dataType: DataType    
    reportingPartner: Partner
    periodRule: String
    name: String
    startDate: Date
    endDate: Date
    expectedDay: String
    workingDays: String
    isInPeriodReporter: Boolean
    weekOfMonth: Float
    monthOfQuarter: Float
  }

  type DataType {
    sid: ID
    createDate: Date
    updateDate: Date
    type: String
  }

  type SubmissionScheduleNotification {
    sid: ID
    createDate: Date
    updateDate: Date
    customerSid: ID
    submissionScheduleSid: ID
    notificationType: NotificationType
    serviceUser: ServiceUser
  }

  enum NotificationType {
    PARSE_SUCCESS
    LATE
    PARSE_FAIL
    EXPECTED
  }

  input SubmissionPeriodFilters {
    sid: IDFilter
    createDate: DateFilter
    updateDate: DateFilter
    customerSid: IDFilter
    expectedDate: DateFilter
    periodStartDate: DateFilter
    periodEndDate: DateFilter
    noDataCreateDate: DateFilter
    submissionSchedule: SubmissionScheduleFilters
    status: StringFilter
    reportedFlag: BooleanFilter
    submissionPeriodLineItemView: SubmissionPeriodLineItemViewFilter
    dataFileSummaryInfo: DataFileSummaryInfoFilter
    numberOfFiles: NumberFilter
  }
  
  input SubmissionPeriodLineItemViewFilter {
    salesLineItemCount: NumberFilter
    invLineItemCount: NumberFilter
    earliestFileSubmissionDate: DateFilter
  }

  input DataFileSummaryInfoFilter{
    numberOfPOSLines: NumberFilter
    numberOfInventoryLines: NumberFilter
    submissionPeriodSid: NumberFilter
    dataFileSid: NumberFilter
    receivedDate: DateFilter
    fileCreateDate: DateFilter
  }

  input SubmissionScheduleFilters {
    sid: IDFilter
    createDate: DateFilter
    updateDate: DateFilter
    customerSid: IDFilter
    reportingPartner: PartnerFilter
    name: StringFilter
    dataType: DataTypeFilter
    periodRule: StringFilter
    expectedDay: StringFilter
    workingDays: StringFilter
    startDate: DateFilter
    endDate: DateFilter
    isInPeriodReporter: BooleanFilter
    weekOfMonth: NumberFilter
    monthOfQuarter: NumberFilter
  }

  input DataTypeFilter {
    sid: IDFilter
    createDate: DateFilter
    updateDate: DateFilter
    type: StringFilter
  }

  input SubmissionScheduleNotificationFilters {
    sid: IDFilter
    createDate: DateFilter
    updateDate: DateFilter
    customerSid: IDFilter
    submissionScheduleSid: IDFilter
    notificationType: StringFilter
    serviceUser: ServiceUserFilters
  }

  input SubmissionPeriodSort {
    sid: SortOption
    createDate: SortOption
    updateDate: SortOption
    expectedDate: SortOption
    periodStartDate: SortOption
    periodEndDate: SortOption
    noDataCreateDate: SortOption
    submissionSchedule: SubmissionScheduleSort
    status: SortOption
    reportedFlag: SortOption
    submissionPeriodLineItemView: SubmissionPeriodLineItemViewSort
    dataFileSummaryInfo: DataFileSummaryInfoSort
    numberOfFiles: SortOption
  }
  
  input SubmissionPeriodLineItemViewSort {
    salesLineItemCount: SortOption
    invLineItemCount: SortOption
    earliestFileSubmissionDate: SortOption
  }

  input DataFileSummaryInfoSort{
    numberOfPOSLines: SortOption
    numberOfInventoryLines: SortOption
    submissionPeriodSid: SortOption
    dataFileSid: SortOption
    receivedDate: SortOption
    fileCreateDate: SortOption
  }

  input SubmissionScheduleSort {
    sid: SortOption
    createDate: SortOption
    updateDate: SortOption
    customerSid: SortOption
    dataType: DataTypeSort
    reportingPartner: PartnerSort
    periodRule: SortOption
    name: SortOption
    startDate: SortOption
    endDate: SortOption
    expectedDay: SortOption
    workingDays: SortOption
    isInPeriodReporter: SortOption
    weekOfMonth: SortOption
    monthOfQuarter: SortOption
  }

  input DataTypeSort {
    sid: SortOption
    createDate: SortOption
    updateDate: SortOption
    type: SortOption
  }

  input SubmissionScheduleNotificationSort {
    sid: SortOption
    createDate: SortOption
    updateDate: SortOption
    notificationType: SortOption
    serviceUser: ServiceUserSort
  }

  input NoDataInput {
    sid: ID!
    noDataReason: String
  }
`;
import { Entity, Column, JoinColumn, OneToOne, VirtualColumn, OneToMany } from 'typeorm';
import { CustomerDomainEntity } from '../base/CustomerDomainEntity';
import {
  returnsSubmissionPeriodLineItemView,
  SubmissionPeriodLineItemView
} from './SubmissionPeriodLineItemView';
import {
  reportedFlagSql,
  statusSql,
  filesCountSql
} from './SubmissionPeriodSql';
import {
  returnsSubmissionSchedule,
  SubmissionSchedule
} from './SubmissionSchedule';
import { ServiceUser, returnsServiceUser } from '../user/ServiceUser';
import { DataFileSummaryInfo } from '../datafile/DataFileSummaryInfo';

export const returnsDataFileSummaryInfo = () => DataFileSummaryInfo;

export const dataFileSummaryInfoInverseSide = (dataFileSummaryInfo) =>
  dataFileSummaryInfo.submissionPeriod;

export const returnsSubmissionPeriod = () => SubmissionPeriod;

@Entity({ name: 'SUBMISSION_PERIOD' })
export class SubmissionPeriod extends CustomerDomainEntity {
  @Column({ name: 'EXPECTED_DATE' })
  expectedDate: Date;

  @Column({ name: 'PERIOD_START_DATE' })
  periodStartDate: Date;

  @Column({ name: 'PERIOD_END_DATE' })
  periodEndDate: Date;

  @Column({ name: 'SUBMISSION_SCHEDULE_SID', select: false })
  submissionScheduleSid: number;

  @Column({ name: 'ON_TIME_OVERRIDE' })
  onTimeOverride: boolean;

  @Column({ name: 'NO_DATA' })
  noData: boolean;

  @Column({ name: 'NO_DATA_REASON' })
  noDataReason: string;

  @Column({ name: 'NO_DATA_CREATE_DATE' })
  noDataCreateDate: Date;

  @Column({ name: 'NO_DATA_SERVICE_USER_SID', select: false })
  noDataServiceUserSid: number;

  @OneToOne(returnsServiceUser)
  @JoinColumn({ name: 'NO_DATA_SERVICE_USER_SID' })
  noDataServiceUser: Promise<ServiceUser>;

  @Column({ name: 'TRACKING_LEVEL' })
  trackingLevel: string;

  @Column({ name: 'EXPECTED_DAY' })
  expectedDay: number;

  @Column({ name: 'WORKING_DAYS' })
  workingDays: string;

  @Column({ name: 'IS_IN_PERIOD_REPORTER' })
  isInPeriodReporter: number;

  @Column({ name: 'DELETED' })
  deleted: boolean;

  @OneToOne(returnsSubmissionSchedule)
  @JoinColumn({ name: 'SUBMISSION_SCHEDULE_SID' })
  submissionSchedule?: Promise<SubmissionSchedule>;

  @VirtualColumn({ query: statusSql })
  status?: string;

  @VirtualColumn({ query: reportedFlagSql })
  reportedFlag: boolean;

  @VirtualColumn( {query : filesCountSql} )
  numberOfFiles?: number;

  @OneToMany(returnsDataFileSummaryInfo,dataFileSummaryInfoInverseSide)
  @JoinColumn({ name: 'SID', referencedColumnName: 'submissionPeriodSid' })
  dataFileSummaryInfo?: Promise<DataFileSummaryInfo[]>;

  @OneToOne(returnsSubmissionPeriodLineItemView)
  @JoinColumn({ name: 'SID', referencedColumnName: 'submissionPeriodSid' })
  submissionPeriodLineItemView?: Promise<SubmissionPeriodLineItemView>;

}
export const getDataFileIdSql = (alias: string) => {
    return `SELECT df.id FROM DATA_FILE df WHERE df.SID = ${alias}.DATA_FILE_SID`;
};

export const getDataFileNameSql = (alias: string) => {
    return `SELECT df.file_name FROM DATA_FILE df WHERE df.SID = ${alias}.DATA_FILE_SID`;
};
import { Inject, Service } from 'typedi';
import { DomainEntityService } from '../base/DomainEntityService';
import { DataFileSummaryInfo } from './DataFileSummaryInfo';
import { CustomerService } from '../customer/CustomerService';
import { SubmissionPeriodService } from '../submission/SubmissionPeriodService';

@Service()
export class DataFileSummaryInfoService extends DomainEntityService<DataFileSummaryInfo> {
  @Inject()
  protected customerService: CustomerService;

  @Inject()
  protected submissionPeriodService: SubmissionPeriodService;

  constructor() {
    super(DataFileSummaryInfo);
  }

  getServiceName() {
    return 'DataFileSummaryInfo';
  }

  async createDataFileSummaryInfo(
    custId: string,
    submissionPeriodSid: number,
    dataFileSid: number,
    numberOfPOSLines: number,
    numberOfInventoryLines: number
  ) {
    const cust = await this.customerService.findOneById(custId);

    await this.create({
      customerSid: cust.sid,
      submissionPeriodSid: submissionPeriodSid,
      dataFileSid: dataFileSid,
      numberOfPOSLines: numberOfPOSLines,
      numberOfInventoryLines: numberOfInventoryLines,
    });
}
}
import { Entity, Column, ManyToOne, JoinColumn, VirtualColumn} from 'typeorm';
import { CustomerDomainEntity } from '../base/CustomerDomainEntity';
import { SubmissionPeriod } from '../submission/SubmissionPeriod';
import { getDataFileIdSql, getDataFileNameSql } from './DataFileSummaryInfoSql';

export const returnsSubmissionPeriods = () => SubmissionPeriod;
export const returnsSummaryInfo = (submissionPeriod) => submissionPeriod.dataFileSummaryInfo;

@Entity({ name: 'DATA_FILE_SUMMARY_INFO' })
export class DataFileSummaryInfo extends CustomerDomainEntity {

    @ManyToOne(returnsSubmissionPeriods,returnsSummaryInfo)
    @JoinColumn({ name: 'SUBMISSION_PERIOD_SID', referencedColumnName:'sid'})
    submissionPeriod: SubmissionPeriod;

    @Column({name:'DATA_FILE_SID'})
    dataFileSid: number;

    @Column({name: 'CUSTOMER_SID'})
    customerSid: number;

    @Column({name:'NUM_SLIS'})
    numberOfPOSLines: number;

    @Column({name:'NUM_ILIS'})
    numberOfInventoryLines: number;

    @Column({name: 'CREATE_DATE'})
    receivedDate: Date;
    
    @Column({ name: 'SUBMISSION_PERIOD_SID', nullable: true })
    submissionPeriodSid: number;

    @VirtualColumn({ query: getDataFileIdSql})
    dataFileId?: string;
    
    @VirtualColumn({ query: getDataFileNameSql})
    dataFileName?: string;
}

import { Customer } from './customer/Customer';
import { Partner } from './partner/Partner';
import { Product } from './product/Product';
import { DynamicAttrs } from './attribute/DynamicAttrs';
import { DynamicAttrMetadata } from './attribute/DynamicAttrMetadata';
import { Sales } from './sales/Sales';
import { Address } from './address/Address';
import { Currency } from './base/Currency';
import { DataFile } from './datafile/DataFile';
import { Country } from './address/Country';
import { SalesMatchInfo } from './sales/SalesMatchInfo';
import { ProductAggr } from './product/ProductAggr';
import { GsNumber } from './partner/GsNumber';
import { Inventory } from './inventory/Inventory';
import { SubmissionPeriod } from './submission/SubmissionPeriod';
import { InventoryQuantity } from './inventory/InventoryQuantity';
import { QuantityType } from './inventory/QuantityType';
import { InventoryPrice } from './inventory/InventoryPrice';
import { UserEvent } from './event/UserEvent';
import { UserSession } from './event/UserSession';
import { DataFileState } from './datafile/DataFileState';
import { ParserAttempt } from './datafile/ParserAttempt';
import { PartnerOverlayView } from './partner/PartnerOverlayView';
import { DataState } from './base/DataState';
import { SubmissionSchedule } from './submission/SubmissionSchedule';
import { DataType } from './base/DataType';
import { SubmissionPeriodLineItemView } from './submission/SubmissionPeriodLineItemView';
import { SubmissionScheduleNotification } from './submission/SubmissionScheduleNotification';
import { ServiceUser } from './user/ServiceUser';
import { AuditEvent } from './event/AuditEvent';
import { SubmissionScheduleAudit } from './submission/SubmissionScheduleAudit';
import { AuditType } from './event/AuditType';
import { DataFileSummaryInfo } from './datafile/DataFileSummaryInfo';
import { SubmissionPeriodInfoView } from './submission/SubmissionPeriodInfoView';

export const entities = [
  Customer,
  GsNumber,
  Partner,
  Product,
  ProductAggr,
  Sales,
  Inventory,
  SubmissionPeriod,
  SubmissionSchedule,
  SubmissionScheduleNotification,
  DataType,
  SubmissionPeriodLineItemView,
  InventoryQuantity,
  QuantityType,
  InventoryPrice,
  SalesMatchInfo,
  Address,
  Country,
  Currency,
  DataFile,
  DataFileState,
  DataState,
  ParserAttempt,
  PartnerOverlayView,
  DynamicAttrs,
  DynamicAttrMetadata,
  UserEvent,
  UserSession,
  ServiceUser,
  AuditEvent,
  SubmissionScheduleAudit,
  AuditType,
  DataFileSummaryInfo
];
export const SubmissionDef = `
  type Query {
    submissionPeriods(
      offset: Float, 
      limit: Float,
      filters: SubmissionPeriodFilters,
      sort: SubmissionPeriodSort
    ): [SubmissionPeriod]
    submissionSchedules(
      offset: Float, 
      limit: Float,
      filters: SubmissionScheduleFilters, 
      sort: SubmissionScheduleSort
    ): [SubmissionSchedule]
    submissionScheduleNotifications(
      submissionScheduleSid: ID,
      offset: Float,
      limit: Float,
      filters: SubmissionScheduleNotificationFilters,
      sort: SubmissionScheduleNotificationSort
    ): [SubmissionScheduleNotification]
  }

  type Mutation {
    markNoData(data: [NoDataInput]): [MutationResponse] @auth(object: SubmissionPeriod)
  }

  type SubmissionPeriod {
    sid: ID
    createDate: Date
    updateDate: Date
    customerSid: ID
    expectedDate: Date
    periodStartDate: Date
    periodEndDate: Date
    noData: Boolean
    noDataReason: String
    noDataCreateDate: Date
    onTimeOverride: Boolean
    expectedDay: String
    workingDays: String
    isInPeriodReporter: Float
    trackingLevel: String
    submissionSchedule: SubmissionSchedule
    status: String
    reportedFlag: Boolean
    numberOfFiles: Float
    dataFileSummaryInfo: [DataFileSummaryInfo]
    submissionPeriodInfoView: SubmissionPeriodInfoView
    submissionPeriodLineItemView: SubmissionPeriodLineItemView
    noDataServiceUser: ServiceUser
  }

  type SubmissionPeriodLineItemView {
    salesLineItemCount: Float
    invLineItemCount: Float
    earliestFileSubmissionDate: Date
  }

  type SubmissionPeriodInfoView {
    numberOfInventoryLines: Float
    numberOfPOSLines:Float
    fileName: String
    fileId: Float
  }

  type DataFileSummaryInfo{
    numberOfPOSLines: Float
    numberOfInventoryLines: Float
    submissionPeriodSid: Float
    dataFileSid: Float
    receivedDate: Date
    fileCreateDate: Date
    dataFileId: String
    dataFileName: String
  }
  
  type SubmissionSchedule {
    sid: ID
    createDate: Date
    updateDate: Date
    customerSid: ID
    dataType: DataType    
    reportingPartner: Partner
    periodRule: String
    name: String
    startDate: Date
    endDate: Date
    expectedDay: String
    workingDays: String
    isInPeriodReporter: Boolean
    weekOfMonth: Float
    monthOfQuarter: Float
  }

  type DataType {
    sid: ID
    createDate: Date
    updateDate: Date
    type: String
  }

  type SubmissionScheduleNotification {
    sid: ID
    createDate: Date
    updateDate: Date
    customerSid: ID
    submissionScheduleSid: ID
    notificationType: NotificationType
    serviceUser: ServiceUser
  }

  enum NotificationType {
    PARSE_SUCCESS
    LATE
    PARSE_FAIL
    EXPECTED
  }

  input SubmissionPeriodFilters {
    sid: IDFilter
    createDate: DateFilter
    updateDate: DateFilter
    customerSid: IDFilter
    expectedDate: DateFilter
    periodStartDate: DateFilter
    periodEndDate: DateFilter
    noDataCreateDate: DateFilter
    submissionSchedule: SubmissionScheduleFilters
    status: StringFilter
    reportedFlag: BooleanFilter
    submissionPeriodLineItemView: SubmissionPeriodLineItemViewFilter
    dataFileSummaryInfo: DataFileSummaryInfoFilter
    numberOfFiles: NumberFilter
  }
  
  input SubmissionPeriodLineItemViewFilter {
    salesLineItemCount: NumberFilter
    invLineItemCount: NumberFilter
    earliestFileSubmissionDate: DateFilter
  }

  input DataFileSummaryInfoFilter{
    numberOfPOSLines: NumberFilter
    numberOfInventoryLines: NumberFilter
    submissionPeriodSid: NumberFilter
    dataFileSid: NumberFilter
    receivedDate: DateFilter
    fileCreateDate: DateFilter
  }

  input SubmissionScheduleFilters {
    sid: IDFilter
    createDate: DateFilter
    updateDate: DateFilter
    customerSid: IDFilter
    reportingPartner: PartnerFilter
    name: StringFilter
    dataType: DataTypeFilter
    periodRule: StringFilter
    expectedDay: StringFilter
    workingDays: StringFilter
    startDate: DateFilter
    endDate: DateFilter
    isInPeriodReporter: BooleanFilter
    weekOfMonth: NumberFilter
    monthOfQuarter: NumberFilter
  }

  input DataTypeFilter {
    sid: IDFilter
    createDate: DateFilter
    updateDate: DateFilter
    type: StringFilter
  }

  input SubmissionScheduleNotificationFilters {
    sid: IDFilter
    createDate: DateFilter
    updateDate: DateFilter
    customerSid: IDFilter
    submissionScheduleSid: IDFilter
    notificationType: StringFilter
    serviceUser: ServiceUserFilters
  }

  input SubmissionPeriodSort {
    sid: SortOption
    createDate: SortOption
    updateDate: SortOption
    expectedDate: SortOption
    periodStartDate: SortOption
    periodEndDate: SortOption
    noDataCreateDate: SortOption
    submissionSchedule: SubmissionScheduleSort
    status: SortOption
    reportedFlag: SortOption
    submissionPeriodLineItemView: SubmissionPeriodLineItemViewSort
    dataFileSummaryInfo: DataFileSummaryInfoSort
    numberOfFiles: SortOption
  }
  
  input SubmissionPeriodLineItemViewSort {
    salesLineItemCount: SortOption
    invLineItemCount: SortOption
    earliestFileSubmissionDate: SortOption
  }

  input DataFileSummaryInfoSort{
    numberOfPOSLines: SortOption
    numberOfInventoryLines: SortOption
    submissionPeriodSid: SortOption
    dataFileSid: SortOption
    receivedDate: SortOption
    fileCreateDate: SortOption
  }

  input SubmissionScheduleSort {
    sid: SortOption
    createDate: SortOption
    updateDate: SortOption
    customerSid: SortOption
    dataType: DataTypeSort
    reportingPartner: PartnerSort
    periodRule: SortOption
    name: SortOption
    startDate: SortOption
    endDate: SortOption
    expectedDay: SortOption
    workingDays: SortOption
    isInPeriodReporter: SortOption
    weekOfMonth: SortOption
    monthOfQuarter: SortOption
  }

  input DataTypeSort {
    sid: SortOption
    createDate: SortOption
    updateDate: SortOption
    type: SortOption
  }

  input SubmissionScheduleNotificationSort {
    sid: SortOption
    createDate: SortOption
    updateDate: SortOption
    notificationType: SortOption
    serviceUser: ServiceUserSort
  }

  input NoDataInput {
    sid: ID!
    noDataReason: String
  }
`;
import { Entity, Column, JoinColumn, OneToOne, VirtualColumn, OneToMany, ManyToMany, ManyToOne } from 'typeorm';
import { CustomerDomainEntity } from '../base/CustomerDomainEntity';
import {
  returnsSubmissionPeriodLineItemView,
  SubmissionPeriodLineItemView
} from './SubmissionPeriodLineItemView';
import {
  reportedFlagSql,
  statusSql,
  fileIdsSql,
  filesCountSql,
  filesDataSql
} from './SubmissionPeriodSql';
import {
  returnsSubmissionSchedule,
  SubmissionSchedule
} from './SubmissionSchedule';
import { ServiceUser, returnsServiceUser } from '../user/ServiceUser';
import { DataFileSummaryInfo, returnsSummaryInfo } from '../datafile/DataFileSummaryInfo';
import { SubmissionPeriodInfoView } from './SubmissionPeriodInfoView';

export const returnsDataFileSummaryInfo = () => DataFileSummaryInfo;

export const dataFileSummaryInfoInverseSide = (dataFileSummaryInfo) =>
  dataFileSummaryInfo.submissionPeriod;

export const returnsSubmissionPeriod = () => SubmissionPeriod;

@Entity({ name: 'SUBMISSION_PERIOD' })
export class SubmissionPeriod extends CustomerDomainEntity {
  @Column({ name: 'EXPECTED_DATE' })
  expectedDate: Date;

  @Column({ name: 'PERIOD_START_DATE' })
  periodStartDate: Date;

  @Column({ name: 'PERIOD_END_DATE' })
  periodEndDate: Date;

  @Column({ name: 'SUBMISSION_SCHEDULE_SID', select: false })
  submissionScheduleSid: number;

  @Column({ name: 'ON_TIME_OVERRIDE' })
  onTimeOverride: boolean;

  @Column({ name: 'NO_DATA' })
  noData: boolean;

  @Column({ name: 'NO_DATA_REASON' })
  noDataReason: string;

  @Column({ name: 'NO_DATA_CREATE_DATE' })
  noDataCreateDate: Date;

  @Column({ name: 'NO_DATA_SERVICE_USER_SID', select: false })
  noDataServiceUserSid: number;

  @OneToOne(returnsServiceUser)
  @JoinColumn({ name: 'NO_DATA_SERVICE_USER_SID' })
  noDataServiceUser: Promise<ServiceUser>;

  @Column({ name: 'TRACKING_LEVEL' })
  trackingLevel: string;

  @Column({ name: 'EXPECTED_DAY' })
  expectedDay: number;

  @Column({ name: 'WORKING_DAYS' })
  workingDays: string;

  @Column({ name: 'IS_IN_PERIOD_REPORTER' })
  isInPeriodReporter: number;

  @Column({ name: 'DELETED' })
  deleted: boolean;

  @OneToOne(returnsSubmissionSchedule)
  @JoinColumn({ name: 'SUBMISSION_SCHEDULE_SID' })
  submissionSchedule?: Promise<SubmissionSchedule>;

  @VirtualColumn({ query: statusSql })
  status?: string;

  @VirtualColumn({ query: reportedFlagSql })
  reportedFlag: boolean;

  // @VirtualColumn( {query : fileIdsSql} )
  // fileIds?: string;

  // firstFileId?: string;

  // firstFileName?: string;

  // firstFileCreateDate?: Date;

  @VirtualColumn( {query : filesCountSql} )
  numberOfFiles?: number;

  @OneToOne(returnsDataFileSummaryInfo)
  @JoinColumn({ name: 'SID', referencedColumnName: 'submissionPeriodSid' })
  submissionPeriodInfoView?: Promise<SubmissionPeriodInfoView>;

  @OneToMany(returnsDataFileSummaryInfo,dataFileSummaryInfoInverseSide)
  @JoinColumn({ name: 'SID', referencedColumnName: 'submissionPeriodSid' })
  dataFileSummaryInfo?: Promise<DataFileSummaryInfo[]>;

  // this is the aggregation that matches the reporting partner
  // dataFileSummaryInfo: DataFileSummaryInfo;

  @OneToOne(returnsSubmissionPeriodLineItemView)
  @JoinColumn({ name: 'SID', referencedColumnName: 'submissionPeriodSid' })
  submissionPeriodLineItemView?: Promise<SubmissionPeriodLineItemView>;

}
import { Entity, Column, ManyToOne, JoinColumn, OneToMany, VirtualColumn} from 'typeorm';
import { CustomerDomainEntity } from '../base/CustomerDomainEntity';
import { returnsSubmissionPeriod } from '../submission/SubmissionPeriod';
import { SubmissionPeriod } from '../submission/SubmissionPeriod';
import {getDataFileIdSql, getDataFileNameSql} from './DataFileSummaryInfoSql';

export const returnsSubmissionPeriods = () => SubmissionPeriod;
export const returnsSummaryInfo = (submissionPeriod) => submissionPeriod.dataFileSummaryInfo;

@Entity({ name: 'DATA_FILE_SUMMARY_INFO' })
export class DataFileSummaryInfo extends CustomerDomainEntity {

    @ManyToOne(returnsSubmissionPeriods,returnsSummaryInfo)
    @JoinColumn({ name: 'SUBMISSION_PERIOD_SID', referencedColumnName:'sid'})
    submissionPeriod: SubmissionPeriod;

    // @ManyToOne(returnsUserSession)
    // @JoinColumn({ name: 'USER_SESSION_SID' })
    // userSession?: Promise<UserSession>;

    @Column({name:'DATA_FILE_SID'})
    dataFileSid: number;

    @Column({name: 'CUSTOMER_SID'})
    customerSid: number;

    @Column({name:'NUM_SLIS'})
    numberOfPOSLines: number;

    @Column({name:'NUM_ILIS'})
    numberOfInventoryLines: number;

    @Column({name: 'CREATE_DATE'})
    receivedDate: Date;
    
    // specifying that submissionPeriodSid can be null
    @Column({ name: 'SUBMISSION_PERIOD_SID', nullable: true })
    submissionPeriodSid: number;

    // VirtualColumn to get DataFile information
    @VirtualColumn({ query: getDataFileIdSql})
    dataFileId?: string;

    // VirtualColumn to get DataFile information
    @VirtualColumn({ query: getDataFileNameSql})
    dataFileName?: string;

    // @VirtualColumn( {query : fileIdSql} )
    // fileId?: number[];

    // @VirtualColumn( {query : filesCountSql} )
    // numberOfFiles?: number;
}

import { Entity, Column, JoinColumn, OneToOne, VirtualColumn, OneToMany, ManyToMany, ManyToOne } from 'typeorm';
import { CustomerDomainEntity } from '../base/CustomerDomainEntity';
import {
  returnsSubmissionPeriodLineItemView,
  SubmissionPeriodLineItemView
} from './SubmissionPeriodLineItemView';
import {
  reportedFlagSql,
  statusSql,
  fileIdsSql,
  filesCountSql,
  filesDataSql
} from './SubmissionPeriodSql';
import {
  returnsSubmissionSchedule,
  SubmissionSchedule
} from './SubmissionSchedule';
import { ServiceUser, returnsServiceUser } from '../user/ServiceUser';
import { DataFileSummaryInfo, returnsSummaryInfo } from '../datafile/DataFileSummaryInfo';
import { SubmissionPeriodInfoView } from './SubmissionPeriodInfoView';

export const returnsDataFileSummaryInfo = () => DataFileSummaryInfo;

export const dataFileSummaryInfoInverseSide = (dataFileSummaryInfo) =>
  dataFileSummaryInfo.submissionPeriod;

export const returnsSubmissionPeriod = () => SubmissionPeriod;

@Entity({ name: 'SUBMISSION_PERIOD' })
export class SubmissionPeriod extends CustomerDomainEntity {
  @Column({ name: 'EXPECTED_DATE' })
  expectedDate: Date;

  @Column({ name: 'PERIOD_START_DATE' })
  periodStartDate: Date;

  @Column({ name: 'PERIOD_END_DATE' })
  periodEndDate: Date;

  @Column({ name: 'SUBMISSION_SCHEDULE_SID', select: false })
  submissionScheduleSid: number;

  @Column({ name: 'ON_TIME_OVERRIDE' })
  onTimeOverride: boolean;

  @Column({ name: 'NO_DATA' })
  noData: boolean;

  @Column({ name: 'NO_DATA_REASON' })
  noDataReason: string;

  @Column({ name: 'NO_DATA_CREATE_DATE' })
  noDataCreateDate: Date;

  @Column({ name: 'NO_DATA_SERVICE_USER_SID', select: false })
  noDataServiceUserSid: number;

  @OneToOne(returnsServiceUser)
  @JoinColumn({ name: 'NO_DATA_SERVICE_USER_SID' })
  noDataServiceUser: Promise<ServiceUser>;

  @Column({ name: 'TRACKING_LEVEL' })
  trackingLevel: string;

  @Column({ name: 'EXPECTED_DAY' })
  expectedDay: number;

  @Column({ name: 'WORKING_DAYS' })
  workingDays: string;

  @Column({ name: 'IS_IN_PERIOD_REPORTER' })
  isInPeriodReporter: number;

  @Column({ name: 'DELETED' })
  deleted: boolean;

  @OneToOne(returnsSubmissionSchedule)
  @JoinColumn({ name: 'SUBMISSION_SCHEDULE_SID' })
  submissionSchedule?: Promise<SubmissionSchedule>;

  @VirtualColumn({ query: statusSql })
  status?: string;

  @VirtualColumn({ query: reportedFlagSql })
  reportedFlag: boolean;

  // @VirtualColumn( {query : fileIdsSql} )
  // fileIds?: string;

  // firstFileId?: string;

  // firstFileName?: string;

  // firstFileCreateDate?: Date;

  @VirtualColumn( {query : filesCountSql} )
  numberOfFiles?: number;

  @OneToOne(returnsDataFileSummaryInfo)
  @JoinColumn({ name: 'SID', referencedColumnName: 'submissionPeriodSid' })
  submissionPeriodInfoView?: Promise<SubmissionPeriodInfoView>;

  @OneToMany(returnsDataFileSummaryInfo,dataFileSummaryInfoInverseSide)
  @JoinColumn({ name: 'SID', referencedColumnName: 'submissionPeriodSid' })
  dataFileSummaryInfo: Promise<DataFileSummaryInfo[]>;

  // this is the aggregation that matches the reporting partner
  // dataFileSummaryInfo: DataFileSummaryInfo;

  @OneToOne(returnsSubmissionPeriodLineItemView)
  @JoinColumn({ name: 'SID', referencedColumnName: 'submissionPeriodSid' })
  submissionPeriodLineItemView?: Promise<SubmissionPeriodLineItemView>;

}
import { Entity, Column, ManyToOne, JoinColumn, OneToMany, VirtualColumn} from 'typeorm';
import { CustomerDomainEntity } from '../base/CustomerDomainEntity';
import { returnsSubmissionPeriod } from '../submission/SubmissionPeriod';
import { SubmissionPeriod } from '../submission/SubmissionPeriod';
import {getDataFileIdSql, getDataFileNameSql} from './DataFileSummaryInfoSql';

export const returnsSubmissionPeriods = () => SubmissionPeriod;
export const returnsSummaryInfo = (submissionPeriod) => submissionPeriod.dataFileSummaryInfo;

@Entity({ name: 'DATA_FILE_SUMMARY_INFO' })
export class DataFileSummaryInfo extends CustomerDomainEntity {

    @ManyToOne(returnsSubmissionPeriods,returnsSummaryInfo)
    @JoinColumn({ name: 'SUBMISSION_PERIOD_SID', referencedColumnName:'sid'})
    submissionPeriod: SubmissionPeriod;

    // @ManyToOne(returnsUserSession)
    // @JoinColumn({ name: 'USER_SESSION_SID' })
    // userSession?: Promise<UserSession>;

    @Column({name:'DATA_FILE_SID'})
    dataFileSid: number;

    @Column({name: 'CUSTOMER_SID'})
    customerSid: number;

    @Column({name:'NUM_SLIS'})
    numberOfPOSLines: number;

    @Column({name:'NUM_ILIS'})
    numberOfInventoryLines: number;

    @Column({name: 'CREATE_DATE'})
    receivedDate: Date;
    
    // specifying that submissionPeriodSid can be null
    @Column({ name: 'SUBMISSION_PERIOD_SID', nullable: true })
    submissionPeriodSid: number;

    // VirtualColumn to get DataFile information
    @VirtualColumn({ query: getDataFileIdSql})
    dataFileId?: string;

    // VirtualColumn to get DataFile information
    @VirtualColumn({ query: getDataFileNameSql})
    dataFileName?: string;

    // @VirtualColumn( {query : fileIdSql} )
    // fileId?: number[];

    // @VirtualColumn( {query : filesCountSql} )
    // numberOfFiles?: number;
}

export const SubmissionDef = `
  type Query {
    submissionPeriods(
      offset: Float, 
      limit: Float,
      filters: SubmissionPeriodFilters,
      sort: SubmissionPeriodSort
    ): [SubmissionPeriod]
    submissionSchedules(
      offset: Float, 
      limit: Float,
      filters: SubmissionScheduleFilters, 
      sort: SubmissionScheduleSort
    ): [SubmissionSchedule]
    submissionScheduleNotifications(
      submissionScheduleSid: ID,
      offset: Float,
      limit: Float,
      filters: SubmissionScheduleNotificationFilters,
      sort: SubmissionScheduleNotificationSort
    ): [SubmissionScheduleNotification]
  }

  type Mutation {
    markNoData(data: [NoDataInput]): [MutationResponse] @auth(object: SubmissionPeriod)
  }

  type SubmissionPeriod {
    sid: ID
    createDate: Date
    updateDate: Date
    customerSid: ID
    expectedDate: Date
    periodStartDate: Date
    periodEndDate: Date
    noData: Boolean
    noDataReason: String
    noDataCreateDate: Date
    onTimeOverride: Boolean
    expectedDay: String
    workingDays: String
    isInPeriodReporter: Float
    trackingLevel: String
    submissionSchedule: SubmissionSchedule
    status: String
    reportedFlag: Boolean
    numberOfFiles: Float
    dataFileSummaryInfo: DataFileSummaryInfo
    submissionPeriodInfoView: SubmissionPeriodInfoView
    submissionPeriodLineItemView: SubmissionPeriodLineItemView
    noDataServiceUser: ServiceUser
  }

  type SubmissionPeriodLineItemView {
    salesLineItemCount: Float
    invLineItemCount: Float
    earliestFileSubmissionDate: Date
  }

  type SubmissionPeriodInfoView {
    numberOfInventoryLines: Float
    numberOfPOSLines:Float
    fileName: String
    fileId: Float
  }

  type DataFileSummaryInfo{
    numberOfPOSLines: Float
    numberOfInventoryLines: Float
    submissionPeriodSid: Float
    dataFileSid: Float
    receivedDate: Date
    fileCreateDate: Date
    dataFileId: String
    dataFileName: String
  }
  
  type SubmissionSchedule {
    sid: ID
    createDate: Date
    updateDate: Date
    customerSid: ID
    dataType: DataType    
    reportingPartner: Partner
    periodRule: String
    name: String
    startDate: Date
    endDate: Date
    expectedDay: String
    workingDays: String
    isInPeriodReporter: Boolean
    weekOfMonth: Float
    monthOfQuarter: Float
  }

  type DataType {
    sid: ID
    createDate: Date
    updateDate: Date
    type: String
  }

  type SubmissionScheduleNotification {
    sid: ID
    createDate: Date
    updateDate: Date
    customerSid: ID
    submissionScheduleSid: ID
    notificationType: NotificationType
    serviceUser: ServiceUser
  }

  enum NotificationType {
    PARSE_SUCCESS
    LATE
    PARSE_FAIL
    EXPECTED
  }

  input SubmissionPeriodFilters {
    sid: IDFilter
    createDate: DateFilter
    updateDate: DateFilter
    customerSid: IDFilter
    expectedDate: DateFilter
    periodStartDate: DateFilter
    periodEndDate: DateFilter
    submissionSchedule: SubmissionScheduleFilters
    status: StringFilter
    reportedFlag: BooleanFilter
    submissionPeriodLineItemView: SubmissionPeriodLineItemViewFilter
    dataFileSummaryInfo: DataFileSummaryInfoFilter
    numberOfFiles: NumberFilter
  }
  
  input SubmissionPeriodLineItemViewFilter {
    salesLineItemCount: NumberFilter
    invLineItemCount: NumberFilter
    earliestFileSubmissionDate: DateFilter
  }

  input DataFileSummaryInfoFilter{
    numberOfPOSLines: NumberFilter
    numberOfInventoryLines: NumberFilter
    submissionPeriodSid: NumberFilter
    dataFileSid: NumberFilter
    receivedDate: DateFilter
    fileCreateDate: DateFilter
  }

  input SubmissionScheduleFilters {
    sid: IDFilter
    createDate: DateFilter
    updateDate: DateFilter
    customerSid: IDFilter
    reportingPartner: PartnerFilter
    name: StringFilter
    dataType: DataTypeFilter
    periodRule: StringFilter
    expectedDay: StringFilter
    workingDays: StringFilter
    startDate: DateFilter
    endDate: DateFilter
    isInPeriodReporter: BooleanFilter
    weekOfMonth: NumberFilter
    monthOfQuarter: NumberFilter
  }

  input DataTypeFilter {
    sid: IDFilter
    createDate: DateFilter
    updateDate: DateFilter
    type: StringFilter
  }

  input SubmissionScheduleNotificationFilters {
    sid: IDFilter
    createDate: DateFilter
    updateDate: DateFilter
    customerSid: IDFilter
    submissionScheduleSid: IDFilter
    notificationType: StringFilter
    serviceUser: ServiceUserFilters
  }

  input SubmissionPeriodSort {
    sid: SortOption
    createDate: SortOption
    updateDate: SortOption
    expectedDate: SortOption
    periodStartDate: SortOption
    periodEndDate: SortOption
    submissionSchedule: SubmissionScheduleSort
    status: SortOption
    reportedFlag: SortOption
    submissionPeriodLineItemView: SubmissionPeriodLineItemViewSort
    dataFileSummaryInfo: DataFileSummaryInfoSort
    numberOfFiles: SortOption
  }
  
  input SubmissionPeriodLineItemViewSort {
    salesLineItemCount: SortOption
    invLineItemCount: SortOption
    earliestFileSubmissionDate: SortOption
  }

  input DataFileSummaryInfoSort{
    numberOfPOSLines: SortOption
    numberOfInventoryLines: SortOption
    submissionPeriodSid: SortOption
    dataFileSid: SortOption
    receivedDate: SortOption
    fileCreateDate: SortOption
  }

  input SubmissionScheduleSort {
    sid: SortOption
    createDate: SortOption
    updateDate: SortOption
    customerSid: SortOption
    dataType: DataTypeSort
    reportingPartner: PartnerSort
    periodRule: SortOption
    name: SortOption
    startDate: SortOption
    endDate: SortOption
    expectedDay: SortOption
    workingDays: SortOption
    isInPeriodReporter: SortOption
    weekOfMonth: SortOption
    monthOfQuarter: SortOption
  }

  input DataTypeSort {
    sid: SortOption
    createDate: SortOption
    updateDate: SortOption
    type: SortOption
  }

  input SubmissionScheduleNotificationSort {
    sid: SortOption
    createDate: SortOption
    updateDate: SortOption
    notificationType: SortOption
    serviceUser: ServiceUserSort
  }

  input NoDataInput {
    sid: ID!
    noDataReason: String
  }
`;
import { Entity, Column, JoinColumn, OneToOne, VirtualColumn, OneToMany, ManyToMany, ManyToOne } from 'typeorm';
import { CustomerDomainEntity } from '../base/CustomerDomainEntity';
import {
  returnsSubmissionPeriodLineItemView,
  SubmissionPeriodLineItemView
} from './SubmissionPeriodLineItemView';
import {
  reportedFlagSql,
  statusSql,
  fileIdsSql,
  filesCountSql,
  filesDataSql
} from './SubmissionPeriodSql';
import {
  returnsSubmissionSchedule,
  SubmissionSchedule
} from './SubmissionSchedule';
import { ServiceUser, returnsServiceUser } from '../user/ServiceUser';
import { DataFileSummaryInfo, returnsSummaryInfo } from '../datafile/DataFileSummaryInfo';
import { SubmissionPeriodInfoView } from './SubmissionPeriodInfoView';

export const returnsDataFileSummaryInfo = () => DataFileSummaryInfo;

export const dataFileSummaryInfoInverseSide = (dataFileSummaryInfo) =>
  dataFileSummaryInfo.submissionPeriod;

  export const returnsSubmissionPeriod = () => SubmissionPeriod;

@Entity({ name: 'SUBMISSION_PERIOD' })
export class SubmissionPeriod extends CustomerDomainEntity {
  @Column({ name: 'EXPECTED_DATE' })
  expectedDate: Date;

  @Column({ name: 'PERIOD_START_DATE' })
  periodStartDate: Date;

  @Column({ name: 'PERIOD_END_DATE' })
  periodEndDate: Date;

  @Column({ name: 'SUBMISSION_SCHEDULE_SID', select: false })
  submissionScheduleSid: number;

  @Column({ name: 'ON_TIME_OVERRIDE' })
  onTimeOverride: boolean;

  @Column({ name: 'NO_DATA' })
  noData: boolean;

  @Column({ name: 'NO_DATA_REASON' })
  noDataReason: string;

  @Column({ name: 'NO_DATA_CREATE_DATE' })
  noDataCreateDate: Date;

  @Column({ name: 'NO_DATA_SERVICE_USER_SID', select: false })
  noDataServiceUserSid: number;

  @OneToOne(returnsServiceUser)
  @JoinColumn({ name: 'NO_DATA_SERVICE_USER_SID' })
  noDataServiceUser: Promise<ServiceUser>;

  @Column({ name: 'TRACKING_LEVEL' })
  trackingLevel: string;

  @Column({ name: 'EXPECTED_DAY' })
  expectedDay: number;

  @Column({ name: 'WORKING_DAYS' })
  workingDays: string;

  @Column({ name: 'IS_IN_PERIOD_REPORTER' })
  isInPeriodReporter: number;

  @Column({ name: 'DELETED' })
  deleted: boolean;

  @OneToOne(returnsSubmissionSchedule)
  @JoinColumn({ name: 'SUBMISSION_SCHEDULE_SID' })
  submissionSchedule?: Promise<SubmissionSchedule>;

  @VirtualColumn({ query: statusSql })
  status?: string;

  @VirtualColumn({ query: reportedFlagSql })
  reportedFlag: boolean;

  @VirtualColumn( {query : fileIdsSql} )
  fileIds?: string;

  firstFileId?: string;

  firstFileName?: string;

  firstFileCreateDate?: Date;

  @VirtualColumn( {query : filesCountSql} )
  numberOfFiles?: number;

  @OneToOne(returnsDataFileSummaryInfo)
  @JoinColumn({ name: 'SID', referencedColumnName: 'submissionPeriodSid' })
  submissionPeriodInfoView?: Promise<SubmissionPeriodInfoView>;

  @OneToMany(returnsDataFileSummaryInfo,dataFileSummaryInfoInverseSide)
  @JoinColumn({ name: 'SID', referencedColumnName: 'submissionPeriodSid' })
  dataFileSummaryInfo: Promise<DataFileSummaryInfo>

  // this is the aggregation that matches the reporting partner
  // dataFileSummaryInfo: DataFileSummaryInfo;

  @OneToOne(returnsSubmissionPeriodLineItemView)
  @JoinColumn({ name: 'SID', referencedColumnName: 'submissionPeriodSid' })
  submissionPeriodLineItemView?: Promise<SubmissionPeriodLineItemView>;

}
import { Entity, Column, ManyToOne, JoinColumn, OneToMany, VirtualColumn} from 'typeorm';
import { CustomerDomainEntity } from '../base/CustomerDomainEntity';
import { returnsSubmissionPeriod } from '../submission/SubmissionPeriod';
import { SubmissionPeriod } from '../submission/SubmissionPeriod';
import {getDataFileIdSql, getDataFileNameSql} from './DataFileSummaryInfoSql';

export const returnsSubmissionPeriods = () => SubmissionPeriod;
export const returnsSummaryInfo = (submissionPeriod) => submissionPeriod.dataFileSummaryInfo;


@Entity({ name: 'DATA_FILE_SUMMARY_INFO' })
export class DataFileSummaryInfo extends CustomerDomainEntity {

    @ManyToOne(returnsSubmissionPeriod)
    @JoinColumn({ name: 'SUBMISSION_PERIOD_SID', referencedColumnName:'sid'})
    submissionPeriod?: Promise<SubmissionPeriod>;

    // @ManyToOne(returnsUserSession)
    // @JoinColumn({ name: 'USER_SESSION_SID' })
    // userSession?: Promise<UserSession>;

    @Column({name:'DATA_FILE_SID'})
    dataFileSid: number;

    @Column({name: 'CUSTOMER_SID'})
    customerSid: number;

    @Column({name:'NUM_SLIS'})
    numberOfPOSLines: number;

    @Column({name:'NUM_ILIS'})
    numberOfInventoryLines: number;

    @Column({name: 'CREATE_DATE'})
    receivedDate: Date;
    
    // specifying that submissionPeriodSid can be null
    @Column({ name: 'SUBMISSION_PERIOD_SID', nullable: true })
    submissionPeriodSid: number;

    // VirtualColumn to get DataFile information
    @VirtualColumn({ query: getDataFileIdSql})
    dataFileId?: string;

    // VirtualColumn to get DataFile information
    @VirtualColumn({ query: getDataFileNameSql})
    dataFileName?: string;

    // @VirtualColumn( {query : fileIdSql} )
    // fileId?: number[];

    // @VirtualColumn( {query : filesCountSql} )
    // numberOfFiles?: number;
}

import { Entity, Column, JoinColumn, OneToOne, VirtualColumn, OneToMany, ManyToMany, ManyToOne } from 'typeorm';
import { CustomerDomainEntity } from '../base/CustomerDomainEntity';
import {
  returnsSubmissionPeriodLineItemView,
  SubmissionPeriodLineItemView
} from './SubmissionPeriodLineItemView';
import {
  reportedFlagSql,
  statusSql,
  fileIdsSql,
  filesCountSql,
  filesDataSql
} from './SubmissionPeriodSql';
import {
  returnsSubmissionSchedule,
  SubmissionSchedule
} from './SubmissionSchedule';
import { ServiceUser, returnsServiceUser } from '../user/ServiceUser';
import { DataFileSummaryInfo, returnsDataFileSummaryInfo } from '../datafile/DataFileSummaryInfo';
import { SubmissionPeriodInfoView } from './SubmissionPeriodInfoView';


export const returnsSubmissionPeriod = () => SubmissionPeriod;
export const dataFileSummaryInfoInverseSide = (dataFileSummaryInfo) =>
  dataFileSummaryInfo.submissionPeriod;

@Entity({ name: 'SUBMISSION_PERIOD' })
export class SubmissionPeriod extends CustomerDomainEntity {
  @Column({ name: 'EXPECTED_DATE' })
  expectedDate: Date;

  @Column({ name: 'PERIOD_START_DATE' })
  periodStartDate: Date;

  @Column({ name: 'PERIOD_END_DATE' })
  periodEndDate: Date;

  @Column({ name: 'SUBMISSION_SCHEDULE_SID', select: false })
  submissionScheduleSid: number;

  @Column({ name: 'ON_TIME_OVERRIDE' })
  onTimeOverride: boolean;

  @Column({ name: 'NO_DATA' })
  noData: boolean;

  @Column({ name: 'NO_DATA_REASON' })
  noDataReason: string;

  @Column({ name: 'NO_DATA_CREATE_DATE' })
  noDataCreateDate: Date;

  @Column({ name: 'NO_DATA_SERVICE_USER_SID', select: false })
  noDataServiceUserSid: number;

  @OneToOne(returnsServiceUser)
  @JoinColumn({ name: 'NO_DATA_SERVICE_USER_SID' })
  noDataServiceUser: Promise<ServiceUser>;

  @Column({ name: 'TRACKING_LEVEL' })
  trackingLevel: string;

  @Column({ name: 'EXPECTED_DAY' })
  expectedDay: number;

  @Column({ name: 'WORKING_DAYS' })
  workingDays: string;

  @Column({ name: 'IS_IN_PERIOD_REPORTER' })
  isInPeriodReporter: number;

  @Column({ name: 'DELETED' })
  deleted: boolean;

  @OneToOne(returnsSubmissionSchedule)
  @JoinColumn({ name: 'SUBMISSION_SCHEDULE_SID' })
  submissionSchedule?: Promise<SubmissionSchedule>;

  @VirtualColumn({ query: statusSql })
  status?: string;

  @VirtualColumn({ query: reportedFlagSql })
  reportedFlag: boolean;

  @VirtualColumn( {query : fileIdsSql} )
  fileIds?: string;

  firstFileId?: string;

  firstFileName?: string;

  firstFileCreateDate?: Date;

  @VirtualColumn( {query : filesCountSql} )
  numberOfFiles?: number;

  @OneToOne(returnsDataFileSummaryInfo)
  @JoinColumn({ name: 'SID', referencedColumnName: 'submissionPeriodSid' })
  submissionPeriodInfoView?: Promise<SubmissionPeriodInfoView>;

  @OneToMany(returnsDataFileSummaryInfo,dataFileSummaryInfoInverseSide)
  @JoinColumn({ name: 'SID', referencedColumnName: 'submissionPeriodSid' })
  dataFileSummaryInfo?: Promise<DataFileSummaryInfo>;

  @OneToOne(returnsSubmissionPeriodLineItemView)
  @JoinColumn({ name: 'SID', referencedColumnName: 'submissionPeriodSid' })
  submissionPeriodLineItemView?: Promise<SubmissionPeriodLineItemView>;

}
import { Entity, Column, ManyToOne, JoinColumn, OneToMany, VirtualColumn} from 'typeorm';
import { CustomerDomainEntity } from '../base/CustomerDomainEntity';
import { returnsSubmissionPeriod } from '../submission/SubmissionPeriod';
import { SubmissionPeriod } from '../submission/SubmissionPeriod';
import {getDataFileIdSql, getDataFileNameSql} from './DataFileSummaryInfoSql';

export const returnsDataFileSummaryInfo = () => DataFileSummaryInfo;
export const returnsSubmissionPeriods = (submissionPeriod) => submissionPeriod.filesData;

@Entity({ name: 'DATA_FILE_SUMMARY_INFO' })
export class DataFileSummaryInfo extends CustomerDomainEntity {

    @ManyToOne(returnsSubmissionPeriod, returnsSubmissionPeriods)
    @JoinColumn([
        { name: 'SUBMISSION_PERIOD_SID', referencedColumnName: 'sid' },
        { name: 'CUSTOMER_SID', referencedColumnName: 'customerSid' }
    ])
    submissionPeriod: SubmissionPeriod;

    @Column({name:'DATA_FILE_SID'})
    dataFileSid: number;

    @Column({name: 'CUSTOMER_SID'})
    customerSid: number;

    @Column({name:'NUM_SLIS'})
    numberOfPOSLines: number;

    @Column({name:'NUM_ILIS'})
    numberOfInventoryLines: number;

    @Column({name: 'CREATE_DATE'})
    receivedDate: Date;
    
    // specifying that submissionPeriodSid can be null
    @Column({ name: 'SUBMISSION_PERIOD_SID', nullable: true })
    submissionPeriodSid: number;

    // VirtualColumn to get DataFile information
    @VirtualColumn({ query: getDataFileIdSql})
    dataFileId?: string;

    // VirtualColumn to get DataFile information
    @VirtualColumn({ query: getDataFileNameSql})
    dataFileName?: string;

    // @VirtualColumn( {query : fileIdSql} )
    // fileId?: number[];

    // @VirtualColumn( {query : filesCountSql} )
    // numberOfFiles?: number;
}

import { Entity, Column, ManyToOne, JoinColumn, OneToMany, VirtualColumn} from 'typeorm';
import { CustomerDomainEntity } from '../base/CustomerDomainEntity';
import { dataFileSummaryInfoInverseSide, returnsSubmissionPeriod } from '../submission/SubmissionPeriod';
import { SubmissionPeriod } from '../submission/SubmissionPeriod';
import { DataFile } from './DataFile';
import {getDataFileIdSql, getDataFileNameSql} from './DataFileSummaryInfoSql';
import {
    filesCountSql, filesDataSql,
  } from '../submission/SubmissionPeriodSql'
import { Alias } from 'typeorm/query-builder/Alias';

export const returnsDataFileSummaryInfo = () => DataFileSummaryInfo;
export const returnsSubmissionPeriods = (submissionPeriod) => submissionPeriod.filesData;

@Entity({ name: 'DATA_FILE_SUMMARY_INFO' })
export class DataFileSummaryInfo extends CustomerDomainEntity {

    @OneToMany(returnsDataFileSummaryInfo,dataFileSummaryInfoInverseSide)
    @JoinColumn([
        { name: 'SUBMISSION_PERIOD_SID', referencedColumnName: 'sid' },
        { name: 'CUSTOMER_SID', referencedColumnName: 'customerSid' }
    ])
    submissionPeriod: SubmissionPeriod;

    @Column({name:'DATA_FILE_SID'})
    dataFileSid: number;

    @Column({name: 'CUSTOMER_SID'})
    customerSid: number;

    @Column({name:'NUM_SLIS'})
    numberOfPOSLines: number;

    @Column({name:'NUM_ILIS'})
    numberOfInventoryLines: number;

    @Column({name: 'CREATE_DATE'})
    receivedDate: Date;
    
    // specifying that submissionPeriodSid can be null
    @Column({ name: 'SUBMISSION_PERIOD_SID', nullable: true })
    submissionPeriodSid: number;

    // VirtualColumn to get DataFile information
    @VirtualColumn({ query: getDataFileIdSql})
    dataFileId?: string;

    // VirtualColumn to get DataFile information
    @VirtualColumn({ query: getDataFileNameSql})
    dataFileName?: string;

    // @VirtualColumn( {query : fileIdSql} )
    // fileId?: number[];

    // @VirtualColumn( {query : filesCountSql} )
    // numberOfFiles?: number;
}

import { Entity, Column, JoinColumn, OneToOne, VirtualColumn, OneToMany, ManyToMany, ManyToOne } from 'typeorm';
import { CustomerDomainEntity } from '../base/CustomerDomainEntity';
import {
  returnsSubmissionPeriodLineItemView,
  SubmissionPeriodLineItemView
} from './SubmissionPeriodLineItemView';
import {
  reportedFlagSql,
  statusSql,
  fileIdsSql,
  filesCountSql,
  filesDataSql
} from './SubmissionPeriodSql';
import {
  returnsSubmissionSchedule,
  SubmissionSchedule
} from './SubmissionSchedule';
import { ServiceUser, returnsServiceUser } from '../user/ServiceUser';
import { DataFileSummaryInfo, returnsDataFileSummaryInfo } from '../datafile/DataFileSummaryInfo';
import { SubmissionPeriodInfoView } from './SubmissionPeriodInfoView';


export const returnsSubmissionPeriod = () => SubmissionPeriod;
export const dataFileSummaryInfoInverseSide = (dataFileSummaryInfo) =>
  dataFileSummaryInfo.submissionPeriod;

@Entity({ name: 'SUBMISSION_PERIOD' })
export class SubmissionPeriod extends CustomerDomainEntity {
  @Column({ name: 'EXPECTED_DATE' })
  expectedDate: Date;

  @Column({ name: 'PERIOD_START_DATE' })
  periodStartDate: Date;

  @Column({ name: 'PERIOD_END_DATE' })
  periodEndDate: Date;

  @Column({ name: 'SUBMISSION_SCHEDULE_SID', select: false })
  submissionScheduleSid: number;

  @Column({ name: 'ON_TIME_OVERRIDE' })
  onTimeOverride: boolean;

  @Column({ name: 'NO_DATA' })
  noData: boolean;

  @Column({ name: 'NO_DATA_REASON' })
  noDataReason: string;

  @Column({ name: 'NO_DATA_CREATE_DATE' })
  noDataCreateDate: Date;

  @Column({ name: 'NO_DATA_SERVICE_USER_SID', select: false })
  noDataServiceUserSid: number;

  @OneToOne(returnsServiceUser)
  @JoinColumn({ name: 'NO_DATA_SERVICE_USER_SID' })
  noDataServiceUser: Promise<ServiceUser>;

  @Column({ name: 'TRACKING_LEVEL' })
  trackingLevel: string;

  @Column({ name: 'EXPECTED_DAY' })
  expectedDay: number;

  @Column({ name: 'WORKING_DAYS' })
  workingDays: string;

  @Column({ name: 'IS_IN_PERIOD_REPORTER' })
  isInPeriodReporter: number;

  @Column({ name: 'DELETED' })
  deleted: boolean;

  @OneToOne(returnsSubmissionSchedule)
  @JoinColumn({ name: 'SUBMISSION_SCHEDULE_SID' })
  submissionSchedule?: Promise<SubmissionSchedule>;

  @VirtualColumn({ query: statusSql })
  status?: string;

  @VirtualColumn({ query: reportedFlagSql })
  reportedFlag: boolean;

  @VirtualColumn( {query : fileIdsSql} )
  fileIds?: string;

  firstFileId?: string;

  firstFileName?: string;

  firstFileCreateDate?: Date;

  @VirtualColumn( {query : filesCountSql} )
  numberOfFiles?: number;

  @OneToOne(returnsDataFileSummaryInfo)
  @JoinColumn({ name: 'SID', referencedColumnName: 'submissionPeriodSid' })
  submissionPeriodInfoView?: Promise<SubmissionPeriodInfoView>;

  @ManyToOne(() => DataFileSummaryInfo)
  @JoinColumn({ name: 'SID', referencedColumnName: 'submissionPeriodSid' })
  dataFileSummaryInfo?: Promise<DataFileSummaryInfo>;

  @OneToOne(returnsSubmissionPeriodLineItemView)
  @JoinColumn({ name: 'SID', referencedColumnName: 'submissionPeriodSid' })
  submissionPeriodLineItemView?: Promise<SubmissionPeriodLineItemView>;

}
import { Entity, Column, JoinColumn, OneToOne, VirtualColumn, OneToMany } from 'typeorm';
import { CustomerDomainEntity } from '../base/CustomerDomainEntity';
import {
  returnsSubmissionPeriodLineItemView,
  SubmissionPeriodLineItemView
} from './SubmissionPeriodLineItemView';
import {
  reportedFlagSql,
  statusSql,
  fileIdsSql,
  filesCountSql,
} from './SubmissionPeriodSql';
import {
  returnsSubmissionSchedule,
  SubmissionSchedule
} from './SubmissionSchedule';
import { ServiceUser, returnsServiceUser } from '../user/ServiceUser';
import { DataFileSummaryInfo, returnsDataFileSummaryInfo } from '../datafile/DataFileSummaryInfo';
import { SubmissionPeriodInfoView } from './SubmissionPeriodInfoView';


export const returnsSubmissionPeriod = () => SubmissionPeriod;
export const dataFileSummaryInfoInverseSide = (dataFileSummaryInfo) =>
  dataFileSummaryInfo.submissionPeriod;

@Entity({ name: 'SUBMISSION_PERIOD' })
export class SubmissionPeriod extends CustomerDomainEntity {
  @Column({ name: 'EXPECTED_DATE' })
  expectedDate: Date;

  @Column({ name: 'PERIOD_START_DATE' })
  periodStartDate: Date;

  @Column({ name: 'PERIOD_END_DATE' })
  periodEndDate: Date;

  @Column({ name: 'SUBMISSION_SCHEDULE_SID', select: false })
  submissionScheduleSid: number;

  @Column({ name: 'ON_TIME_OVERRIDE' })
  onTimeOverride: boolean;

  @Column({ name: 'NO_DATA' })
  noData: boolean;

  @Column({ name: 'NO_DATA_REASON' })
  noDataReason: string;

  @Column({ name: 'NO_DATA_CREATE_DATE' })
  noDataCreateDate: Date;

  @Column({ name: 'NO_DATA_SERVICE_USER_SID', select: false })
  noDataServiceUserSid: number;

  @OneToOne(returnsServiceUser)
  @JoinColumn({ name: 'NO_DATA_SERVICE_USER_SID' })
  noDataServiceUser: Promise<ServiceUser>;

  @Column({ name: 'TRACKING_LEVEL' })
  trackingLevel: string;

  @Column({ name: 'EXPECTED_DAY' })
  expectedDay: number;

  @Column({ name: 'WORKING_DAYS' })
  workingDays: string;

  @Column({ name: 'IS_IN_PERIOD_REPORTER' })
  isInPeriodReporter: number;

  @Column({ name: 'DELETED' })
  deleted: boolean;

  @OneToOne(returnsSubmissionSchedule)
  @JoinColumn({ name: 'SUBMISSION_SCHEDULE_SID' })
  submissionSchedule?: Promise<SubmissionSchedule>;

  @VirtualColumn({ query: statusSql })
  status?: string;

  @VirtualColumn({ query: reportedFlagSql })
  reportedFlag: boolean;

  @VirtualColumn( {query : fileIdsSql} )
  fileIds?: string;

  firstFileId?: string;

  firstFileName?: string;

  firstFileCreateDate?: Date;

  @VirtualColumn( {query : filesCountSql} )
  numberOfFiles?: number;

  @OneToOne(returnsDataFileSummaryInfo)
  @JoinColumn({ name: 'SID', referencedColumnName: 'submissionPeriodSid' })
  submissionPeriodInfoView?: Promise<SubmissionPeriodInfoView>;

  @OneToMany(() => DataFileSummaryInfo, dataFileSummaryInfo => dataFileSummaryInfo.submissionPeriod)
  @JoinColumn({ name: 'SID', referencedColumnName: 'submissionPeriodSid' })
  dataFileSummaryInfo?: DataFileSummaryInfo[];

  @OneToOne(returnsSubmissionPeriodLineItemView)
  @JoinColumn({ name: 'SID', referencedColumnName: 'submissionPeriodSid' })
  submissionPeriodLineItemView?: Promise<SubmissionPeriodLineItemView>;

}
import { Entity, Column, ManyToOne, JoinColumn, VirtualColumn} from 'typeorm';
import { CustomerDomainEntity } from '../base/CustomerDomainEntity';
import { SubmissionPeriod, returnsSubmissionPeriod } from '../submission/SubmissionPeriod';
import {getDataFileIdSql, getDataFileNameSql} from './DataFileSummaryInfoSql';

export const returnsDataFileSummaryInfo = () => DataFileSummaryInfo;
export const returnsInverseSubmissionPeriods = (submissionPeriod) => submissionPeriod.dataFileSummaryInfo;

@Entity({ name: 'DATA_FILE_SUMMARY_INFO' })
export class DataFileSummaryInfo extends CustomerDomainEntity {

    @ManyToOne(() => SubmissionPeriod)
    @JoinColumn({ name: 'SUBMISSION_PERIOD_SID', referencedColumnName: 'sid' })
    submissionPeriod: SubmissionPeriod;

    @Column({name:'DATA_FILE_SID'})
    dataFileSid: number;

    @Column({name: 'CUSTOMER_SID'})
    customerSid: number;

    @Column({name:'NUM_SLIS'})
    numberOfPOSLines: number;

    @Column({name:'NUM_ILIS'})
    numberOfInventoryLines: number;

    @Column({name: 'CREATE_DATE'})
    receivedDate: Date;
    
    // specifying that submissionPeriodSid can be null
    @Column({ name: 'SUBMISSION_PERIOD_SID', nullable: true })
    submissionPeriodSid: number;

    // VirtualColumn to get DataFile information
    @VirtualColumn({ query: getDataFileIdSql})
    dataFileId?: string;

    // VirtualColumn to get DataFile information
    @VirtualColumn({ query: getDataFileNameSql})
    dataFileName?: string;

    // @VirtualColumn( {query : fileIdSql} )
    // fileId?: number[];

    // @VirtualColumn( {query : filesCountSql} )
    // numberOfFiles?: number;
}

select * from information_schema.columns 
where table_name='table1'and column_name like'a%'
version: "1.0"

name: ChannelNetwork

# All actions

actions:
  - name: VIEW
  - name: UPDATE

# All resources

resources:
  # UI Resource for access to kpis tab
  - name: ProductKpiTab
    actions: [VIEW]

    ### Begin productKpi fields

  - name: ProductKpi
    group: productKpi
    actions: [VIEW]

  - name: ProductKpi/*
    group: productKpi
    actions: [VIEW]

    ### End productKpi fields

    ### Begin salesKpi fields

  - name: SalesKpi
    group: salesKpi
    actions: [VIEW]

  - name: SalesKpi/*
    group: salesKpi
    actions: [VIEW]

    ### End salesKpi fields

    ### Begin inventoryKpi fields

  - name: InventoryKpi
    group: inventoryKpi
    actions: [VIEW]

  - name: InventoryKpi/*
    group: inventoryKpi
    actions: [VIEW]

    ### End inventoryKpi fields

    ### Begin filesKpi fields

  - name: FilesKpi
    group: filesKpi
    actions: [VIEW]

  - name: FilesKpi/*
    group: filesKpi
    actions: [VIEW]

    ### End filesKpi fields

    ### Begin ssKpi fields

  - name: SSKpi
    group: ssKpi
    actions: [VIEW]

  - name: SSKpi/*
    group: ssKpi
    actions: [VIEW]

    ### End ssKpi fields


    # UI Resource for access to Products tab
  - name: ProductTab
    actions: [VIEW, UPDATE]

    ### Begin Product Fields

  - name: Product
    group: product
    actions: [VIEW, UPDATE]

  - name: Product/sid
    group: product
    actions: [VIEW]

  - name: Product/createDate
    group: product
    actions: [VIEW]

  - name: Product/updateDate
    group: product
    actions: [VIEW]

  - name: Product/customerSid
    group: product-internal
    actions: [VIEW]

  - name: Product/sku
    group: product
    actions: [VIEW]

  - name: Product/name
    group: product
    actions: [VIEW]

  - name: Product/description
    group: product
    actions: [VIEW]

  - name: Product/productFamily
    group: product
    actions: [VIEW]

  - name: Product/productLine
    group: product
    actions: [VIEW]

  - name: Product/startDate
    group: product
    actions: [VIEW]

  - name: Product/endDate
    group: product
    actions: [VIEW]

  - name: Product/serialized
    group: product-internal
    actions: [VIEW]

  - name: Product/aggregation
    group: product-pos-aggr
    actions: [VIEW]

  - name: Product/aggregation/totalSalesLineCount
    group: product-pos-aggr
    actions: [VIEW]

  - name: Product/aggregation/totalSalesQuantity
    group: product-pos-aggr
    actions: [VIEW]

  - name: Product/aggregation/oldestInvoiceDate
    group: product-pos-aggr
    actions: [VIEW]

    ## Begin Product Dynamic Attrs


  - name: Product/dynamicAttrs
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/sid
    group: product-dynamicAttrs-internal
    actions: [VIEW]
  - name: Product/dynamicAttrs/updateDate
    group: product-dynamicAttrs-internal
    actions: [VIEW]
  - name: Product/dynamicAttrs/createDate
    group: product-dynamicAttrs-internal
    actions: [VIEW]
  - name: Product/dynamicAttrs/attributeType
    group: product-dynamicAttrs-internal
    actions: [VIEW]
  - name: Product/dynamicAttrs/STRING_COL_1
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_2
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_3
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_4
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_5
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_6
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_7
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_8
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_9
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_10
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_11
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_12
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_13
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_14
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_15
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_16
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_17
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_18
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_19
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_20
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_21
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_22
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_23
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_24
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_25
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_26
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_27
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_28
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_29
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/STRING_COL_30
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]

  - name: Product/dynamicAttrs/NUM_COL_1
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/NUM_COL_2
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/NUM_COL_3
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/NUM_COL_4
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/NUM_COL_5
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/NUM_COL_6
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/NUM_COL_7
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/NUM_COL_8
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/NUM_COL_9
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
  - name: Product/dynamicAttrs/NUM_COL_10
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]

  - name: Product/dynamicAttrs/DATE_COL_1
    group: product-dynamicAttrs
    actions: [VIEW, UPDATE]
    ## End Product Dynamic Attrs

    ### End Product Fields

    # UI Resource for access to POS tab
  - name: SalesTab
    actions: [VIEW, UPDATE]

    ### Begin POS Fields

  - name: Sales
    group: sales
    actions: [VIEW, UPDATE]

  - name: Sales/sid
    group: sales
    actions: [VIEW]

  - name: Sales/createDate
    group: sales
    actions: [VIEW]

  - name: Sales/updateDate
    group: sales
    actions: [VIEW]

  - name: Sales/customerSid
    group: sales-internal
    actions: [VIEW]

  - name: Sales/deleted
    group: sales-internal
    actions: [VIEW]

  - name: Sales/branchId
    group: sales
    actions: [VIEW]

  - name: Sales/invoiceNumber
    group: sales
    actions: [VIEW]

  - name: Sales/invoiceDate
    group: sales
    actions: [VIEW]

  - name: Sales/quantity
    group: sales
    actions: [VIEW]

  - name: Sales/reportedSku
    group: sales
    actions: [VIEW, UPDATE]

  - name: Sales/productDescription
    group: sales
    actions: [VIEW]

  - name: Sales/transactionId
    group: sales-internal
    actions: [VIEW]

  - name: Sales/vendorPartNumber
    group: sales
    actions: [VIEW]

  - name: Sales/accountRepresentative
    group: sales
    actions: [VIEW]

  - name: Sales/acquisitionExtendedPrice
    group: sales
    actions: [VIEW]

  - name: Sales/acquisitionUnitPrice
    group: sales
    actions: [VIEW]

  - name: Sales/boolExtendedPrice
    group: sales
    actions: [VIEW]

  - name: Sales/bookUnitPrice
    group: sales
    actions: [VIEW]

  - name: Sales/customerOrderNumber
    group: sales
    actions: [VIEW]

  - name: Sales/debitExtendedPrice
    group: sales
    actions: [VIEW]

  - name: Sales/debitUnitPrice
    group: sales
    actions: [VIEW]

  - name: Sales/designRegistrationNumber
    group: sales
    actions: [VIEW]

  - name: Sales/distributorId
    group: sales
    actions: [VIEW]

  - name: Sales/distributorName
    group: sales
    actions: [VIEW]

  - name: Sales/distributorShipmentNumber
    group: sales
    actions: [VIEW]

  - name: Sales/distributorWarehouseId
    group: sales
    actions: [VIEW]

  - name: Sales/exchangeDate
    group: sales
    actions: [VIEW]

  - name: Sales/exchangeRate
    group: sales
    actions: [VIEW]

  - name: Sales/globalProductClassCode
    group: sales
    actions: [VIEW]

  - name: Sales/legacySalesRecordId
    group: sales
    actions: [VIEW]

  - name: Sales/lengthOfProduction
    group: sales
    actions: [VIEW]

  - name: Sales/manufactureId
    group: sales
    actions: [VIEW]

  - name: Sales/manufactureName
    group: sales
    actions: [VIEW]

  - name: Sales/manufacturerShipmentNumber
    group: sales
    actions: [VIEW]

  - name: Sales/orderNumber
    group: sales
    actions: [VIEW]

  - name: Sales/originalId
    group: sales
    actions: [VIEW]

  - name: Sales/price
    group: sales
    actions: [VIEW]

  - name: Sales/purchaseOrderNumber
    group: sales
    actions: [VIEW]

  - name: Sales/r2rDuplicateType
    group: sales
    actions: [VIEW]

  - name: Sales/regionTerritory
    group: sales
    actions: [VIEW]

  - name: Sales/reportEndingDate
    group: sales
    actions: [VIEW]

  - name: Sales/reportType
    group: sales
    actions: [VIEW]

  - name: Sales/resaleExtendedPrice
    group: sales
    actions: [VIEW]

  - name: Sales/resaeExtension
    group: sales
    actions: [VIEW]

  - name: Sales/resaleUnitPrice
    group: sales
    actions: [VIEW]

  - name: Sales/resubmitted
    group: sales
    actions: [VIEW]

  - name: Sales/reportedProductFamily
    group: sales
    actions: [VIEW]

  - name: Sales/reportedProductLine
    group: sales
    actions: [VIEW]

  - name: Sales/reportedProductName
    group: sales
    actions: [VIEW]

  - name: Sales/shipDate
    group: sales
    actions: [VIEW]

  - name: Sales/shipDebitNumber
    group: sales
    actions: [VIEW]

  - name: Sales/shippingMethod
    group: sales
    actions: [VIEW]

  - name: Sales/spaNumber
    group: sales
    actions: [VIEW]

  - name: Sales/tier
    group: sales
    actions: [VIEW]

  - name: Sales/transactionType
    group: sales
    actions: [VIEW]

  - name: Sales/unitOfMeasure
    group: sales
    actions: [VIEW]

  - name: Sales/vendorPartDescription
    group: sales
    actions: [VIEW]

  - name: Sales/validationCodes
    group: sales
    actions: [VIEW]

  - name: Sales/serialNumbers
    group: sales
    actions: [VIEW]

    # Bill to address


  - name: Sales/billToAddress
    group: sales-bill-to
    actions: [VIEW]

  - name: Sales/billToAddress/*
    group: sales-internal
    actions: [VIEW]

  - name: Sales/billToAddress/entityName
    group: sales-bill-to
    actions: [VIEW]

  - name: Sales/billToAddress/street1
    group: sales-bill-to
    actions: [VIEW]

  - name: Sales/billToAddress/street2
    group: sales-bill-to
    actions: [VIEW]

  - name: Sales/billToAddress/city
    group: sales-bill-to
    actions: [VIEW]

  - name: Sales/billToAddress/stateProvince
    group: sales-bill-to
    actions: [VIEW]

  - name: Sales/billToAddress/postalCode
    group: sales-bill-to
    actions: [VIEW]

  - name: Sales/billToAddress/reportedCountry
    group: sales-bill-to
    actions: [VIEW]

  - name: Sales/billToAddress/country
    group: sales-bill-to
    actions: [VIEW]

  - name: Sales/billToAddress/country/name
    group: sales-bill-to
    actions: [VIEW]

  - name: Sales/billToAddress/country/twoCharCode
    group: sales-bill-to
    actions: [VIEW]

  - name: Sales/billToAddress/country/threeCharCode
    group: sales-bill-to
    actions: [VIEW]

  - name: Sales/billToAddressExternalId
    group: sales-bill-to
    actions: [VIEW]

    # sold to address

  - name: Sales/soldToAddress
    group: sales-sold-to
    actions: [VIEW]

  - name: Sales/soldToAddress/*
    group: sales-internal
    actions: [VIEW]

  - name: Sales/soldToAddress/entityName
    group: sales-sold-to
    actions: [VIEW]

  - name: Sales/soldToAddress/street1
    group: sales-sold-to
    actions: [VIEW]

  - name: Sales/soldToAddress/street2
    group: sales-sold-to
    actions: [VIEW]

  - name: Sales/soldToAddress/city
    group: sales-sold-to
    actions: [VIEW]

  - name: Sales/soldToAddress/stateProvince
    group: sales-sold-to
    actions: [VIEW]

  - name: Sales/soldToAddress/postalCode
    group: sales-sold-to
    actions: [VIEW]

  - name: Sales/soldToAddress/reportedCountry
    group: sales-sold-to
    actions: [VIEW]

  - name: Sales/soldToAddress/country
    group: sales-sold-to
    actions: [VIEW]

  - name: Sales/soldToAddress/country/name
    group: sales-sold-to
    actions: [VIEW]

  - name: Sales/soldToAddress/country/twoCharCode
    group: sales-sold-to
    actions: [VIEW]

  - name: Sales/soldToAddress/country/threeCharCode
    group: sales-sold-to
    actions: [VIEW]

  - name: Sales/soldToAddressExternalId
    group: sales-sold-to
    actions: [VIEW]

    # ship to address

  - name: Sales/shipToAddress
    group: sales-ship-to
    actions: [VIEW]

  - name: Sales/shipToAddress/*
    group: sales-internal
    actions: [VIEW]

  - name: Sales/shipToAddress/entityName
    group: sales-ship-to
    actions: [VIEW]

  - name: Sales/shipToAddress/street1
    group: sales-ship-to
    actions: [VIEW]

  - name: Sales/shipToAddress/street2
    group: sales-ship-to
    actions: [VIEW]

  - name: Sales/shipToAddress/city
    group: sales-ship-to
    actions: [VIEW]

  - name: Sales/shipToAddress/stateProvince
    group: sales-ship-to
    actions: [VIEW]

  - name: Sales/shipToAddress/postalCode
    group: sales-ship-to
    actions: [VIEW]

  - name: Sales/shipToAddress/reportedCountry
    group: sales-ship-to
    actions: [VIEW]

  - name: Sales/shipToAddress/country
    group: sales-ship-to
    actions: [VIEW]

  - name: Sales/shipToAddress/country/name
    group: sales-ship-to
    actions: [VIEW]

  - name: Sales/shipToAddress/country/twoCharCode
    group: sales-ship-to
    actions: [VIEW]

  - name: Sales/shipToAddress/country/threeCharCode
    group: sales-ship-to
    actions: [VIEW]

  - name: Sales/shipToAddressExternalId
    group: sales-ship-to
    actions: [VIEW]

    # sell from address

  - name: Sales/sellFromAddress
    group: sales-sell-from
    actions: [VIEW]

  - name: Sales/sellFromAddress/*
    group: sales-internal
    actions: [VIEW]

  - name: Sales/sellFromAddress/entityName
    group: sales-sell-from
    actions: [VIEW]

  - name: Sales/sellFromAddress/street1
    group: sales-sell-from
    actions: [VIEW]

  - name: Sales/sellFromAddress/street2
    group: sales-sell-from
    actions: [VIEW]

  - name: Sales/sellFromAddress/city
    group: sales-sell-from
    actions: [VIEW]

  - name: Sales/sellFromAddress/stateProvince
    group: sales-sell-from
    actions: [VIEW]

  - name: Sales/sellFromAddress/postalCode
    group: sales-sell-from
    actions: [VIEW]

  - name: Sales/sellFromAddress/reportedCountry
    group: sales-sell-from
    actions: [VIEW]

  - name: Sales/sellFromAddress/country
    group: sales-sell-from
    actions: [VIEW]

  - name: Sales/sellFromAddress/country/name
    group: sales-sell-from
    actions: [VIEW]

  - name: Sales/sellFromAddress/country/twoCharCode
    group: sales-sell-from
    actions: [VIEW]

  - name: Sales/sellFromAddress/country/threeCharCode
    group: sales-sell-from
    actions: [VIEW]

  - name: Sales/sellFromAddressExternalId
    group: sales-sell-from
    actions: [VIEW]

    # ship from address

  - name: Sales/shipFromAddress
    group: sales-ship-from
    actions: [VIEW]

  - name: Sales/shipFromAddress/*
    group: sales-internal
    actions: [VIEW]

  - name: Sales/shipFromAddress/entityName
    group: sales-ship-from
    actions: [VIEW]

  - name: Sales/shipFromAddress/street1
    group: sales-ship-from
    actions: [VIEW]

  - name: Sales/shipFromAddress/street2
    group: sales-ship-from
    actions: [VIEW]

  - name: Sales/shipFromAddress/city
    group: sales-ship-from
    actions: [VIEW]

  - name: Sales/shipFromAddress/stateProvince
    group: sales-ship-from
    actions: [VIEW]

  - name: Sales/shipFromAddress/postalCode
    group: sales-ship-from
    actions: [VIEW]

  - name: Sales/shipFromAddress/reportedCountry
    group: sales-ship-from
    actions: [VIEW]

  - name: Sales/shipFromAddress/country
    group: sales-ship-from
    actions: [VIEW]

  - name: Sales/shipFromAddress/country/name
    group: sales-ship-from
    actions: [VIEW]

  - name: Sales/shipFromAddress/country/twoCharCode
    group: sales-ship-from
    actions: [VIEW]

  - name: Sales/shipFromAddress/country/threeCharCode
    group: sales-ship-from
    actions: [VIEW]

  - name: Sales/shipFromAddressExternalId
    group: sales-ship-from
    actions: [VIEW]

    # sales in address

  - name: Sales/salesInAddress
    group: sales-sales-in
    actions: [VIEW]

  - name: Sales/salesInAddress/*
    group: sales-internal
    actions: [VIEW]

  - name: Sales/salesInAddress/entityName
    group: sales-sales-in
    actions: [VIEW]

  - name: Sales/salesInAddress/street1
    group: sales-sales-in
    actions: [VIEW]

  - name: Sales/salesInAddress/street2
    group: sales-sales-in
    actions: [VIEW]

  - name: Sales/salesInAddress/city
    group: sales-sales-in
    actions: [VIEW]

  - name: Sales/salesInAddress/stateProvince
    group: sales-sales-in
    actions: [VIEW]

  - name: Sales/salesInAddress/postalCode
    group: sales-sales-in
    actions: [VIEW]

  - name: Sales/salesInAddress/reportedCountry
    group: sales-sales-in
    actions: [VIEW]

  - name: Sales/salesInAddress/country
    group: sales-sales-in
    actions: [VIEW]

  - name: Sales/salesInAddress/country/name
    group: sales-sales-in
    actions: [VIEW]

  - name: Sales/salesInAddress/country/twoCharCode
    group: sales-sales-in
    actions: [VIEW]

  - name: Sales/salesInAddress/country/threeCharCode
    group: sales-sales-in
    actions: [VIEW]

  - name: Sales/salesInAddressExternalId
    group: sales-sales-in
    actions: [VIEW]

    # purchasing customer address

  - name: Sales/purchasingCustomerAddress
    group: sales-purchasing-customer
    actions: [VIEW]

  - name: Sales/purchasingCustomerAddress/*
    group: sales-internal
    actions: [VIEW]

  - name: Sales/purchasingCustomerAddress/entityName
    group: sales-purchasing-customer
    actions: [VIEW]

  - name: Sales/purchasingCustomerAddress/street1
    group: sales-purchasing-customer
    actions: [VIEW]

  - name: Sales/purchasingCustomerAddress/street2
    group: sales-purchasing-customer
    actions: [VIEW]

  - name: Sales/purchasingCustomerAddress/city
    group: sales-purchasing-customer
    actions: [VIEW]

  - name: Sales/purchasingCustomerAddress/stateProvince
    group: sales-purchasing-customer
    actions: [VIEW]

  - name: Sales/purchasingCustomerAddress/postalCode
    group: sales-purchasing-customer
    actions: [VIEW]

  - name: Sales/purchasingCustomerAddress/reportedCountry
    group: sales-purchasing-customer
    actions: [VIEW]

  - name: Sales/purchasingCustomerAddress/country
    group: sales-purchasing-customer
    actions: [VIEW]

  - name: Sales/purchasingCustomerAddress/country/name
    group: sales-purchasing-customer
    actions: [VIEW]

  - name: Sales/purchasingCustomerAddress/country/twoCharCode
    group: sales-purchasing-customer
    actions: [VIEW]

  - name: Sales/purchasingCustomerAddress/country/threeCharCode
    group: sales-purchasing-customer
    actions: [VIEW]

  - name: Sales/purchasingCustomerExternalId
    group: sales-purchasing-customer
    actions: [VIEW]

    # derived end customer address

  - name: Sales/derivedEndCustomerAddress
    group: sales-derived-end-customer
    actions: [VIEW]

  - name: Sales/derivedEndCustomerAddress/*
    group: sales-internal
    actions: [VIEW]

  - name: Sales/derivedEndCustomerAddress/entityName
    group: sales-derived-end-customer
    actions: [VIEW]

  - name: Sales/derivedEndCustomerAddress/street1
    group: sales-derived-end-customer
    actions: [VIEW]

  - name: Sales/derivedEndCustomerAddress/street2
    group: sales-derived-end-customer
    actions: [VIEW]

  - name: Sales/derivedEndCustomerAddress/city
    group: sales-derived-end-customer
    actions: [VIEW]

  - name: Sales/derivedEndCustomerAddress/stateProvince
    group: sales-derived-end-customer
    actions: [VIEW]

  - name: Sales/derivedEndCustomerAddress/postalCode
    group: sales-derived-end-customer
    actions: [VIEW]

  - name: Sales/derivedEndCustomerAddress/reportedCountry
    group: sales-derived-end-customer
    actions: [VIEW]

  - name: Sales/derivedEndCustomerAddress/country
    group: sales-derived-end-customer
    actions: [VIEW]

  - name: Sales/derivedEndCustomerAddress/country/name
    group: sales-derived-end-customer
    actions: [VIEW]

  - name: Sales/derivedEndCustomerAddress/country/twoCharCode
    group: sales-derived-end-customer
    actions: [VIEW]

  - name: Sales/derivedEndCustomerAddress/country/threeCharCode
    group: sales-derived-end-customer
    actions: [VIEW]

  - name: Sales/derivedEndCustomerAddressExternalId
    group: sales-derived-end-customer
    actions: [VIEW]

    # data file

  - name: Sales/dataFile
    group: sales-data-file
    actions: [VIEW]

  - name: Sales/dataFile/*
    group: sales-internal
    actions: [VIEW]

  - name: Sales/dataFile/loadDate
    group: sales-data-file
    actions: [VIEW]

  - name: Sales/dataFile/reportDate
    group: sales-data-file
    actions: [VIEW]

  - name: Sales/dataFile/id
    group: sales-data-file
    actions: [VIEW]

  - name: Sales/dataFile/fileName
    group: sales-data-file
    actions: [VIEW]

  - name: Sales/dataFile/recordCount
    group: sales-data-file
    actions: [VIEW]

    # match info

  - name: Sales/productMatchInfo
    group: sales-product-match-info
    actions: [VIEW]

  - name: Sales/productMatchInfo/*
    group: sales-internal
    actions: [VIEW]

  - name: Sales/productMatchInfo/matchedProduct
    group: sales-product-match-info
    actions: [VIEW]

  - name: Sales/productMatchInfo/matchedProduct/sku
    group: sales-product-match-info
    actions: [VIEW]

    # reporting partner

  - name: Sales/reportingPartner
    group: sales-reporting-partner
    actions: [VIEW]

  - name: Sales/reportingPartner/*
    group: sales-internal
    actions: [VIEW]

  - name: Sales/reportingPartner/gsNumbers
    group: sales-reporting-partner
    actions: [VIEW]

  - name: Sales/reportingPartner/gsNumbers/value
    group: sales-reporting-partner
    actions: [VIEW]

    # currency

  - name: Sales/currency
    group: sales-currency
    actions: [VIEW]

  - name: Sales/currency/*
    group: sales-internal
    actions: [VIEW]

  - name: Sales/currency/name
    group: sales-currency
    actions: [VIEW]

    # resale currency

  - name: Sales/resaleCurrency
    group: sales-resale-currency
    actions: [VIEW]

  - name: Sales/resaleCurrency/*
    group: sales-internal
    actions: [VIEW]

  - name: Sales/resaleCurrency/name
    group: sales-resale-currency
    actions: [VIEW]

    # debit currency

  - name: Sales/debtCurrency
    group: sales-debit-currency
    actions: [VIEW]

  - name: Sales/debtCurrency/*
    group: sales-internal
    actions: [VIEW]

  - name: Sales/debtCurrency/name
    group: sales-debit-currency
    actions: [VIEW]

    # book currency

  - name: Sales/bookCurrency
    group: sales-book-currency
    actions: [VIEW]

  - name: Sales/bookCurrency/*
    group: sales-internal
    actions: [VIEW]

  - name: Sales/bookCurrency/name
    group: sales-book-currency
    actions: [VIEW]

    # acquisition currency

  - name: Sales/acquisitionCurrency
    group: sales-acquisition-currency
    actions: [VIEW]

  - name: Sales/acquisitionCurrency/*
    group: sales-internal
    actions: [VIEW]

  - name: Sales/acquisitionCurrency/name
    group: sales-acquisition-currency
    actions: [VIEW]

    ## Begin POS Dynamic Attrs

  - name: Sales/dynamicAttrs
    group: sales-dynamic-attrs
    actions: [VIEW, UPDATE]

  - name: Sales/dynamicAttrs/*
    group: sales-dynamic-attrs
    actions: [VIEW, UPDATE]

  - name: Sales/dynamicAttrs/STRING_COL_1
    group: sales-dynamic-attrs
    actions: [VIEW, UPDATE]

    ## End POS Dynamic Attrs

    ### End POS Fields

    # UI Resource for access to INV tab
  - name: InventoryTab
    actions: [VIEW, UPDATE]

    ### Begin INV Fields

  - name: Inventory
    group: inventory
    actions: [VIEW, UPDATE]

  - name: Inventory/sid
    group: inventory
    actions: [VIEW]

  - name: Inventory/createDate
    group: inventory
    actions: [VIEW]

  - name: Inventory/updateDate
    group: inventory
    actions: [VIEW]

  - name: Inventory/customerSid
    group: inventory-internal
    actions: [VIEW]

  - name: Inventory/deleted
    group: inventory-internal
    actions: [VIEW]

  - name: Inventory/productName
    group: inventory
    actions: [VIEW]

  - name: Inventory/clientDescription
    group: inventory
    actions: [VIEW]

  - name: Inventory/clientSku
    group: inventory
    actions: [VIEW, UPDATE]

  - name: Inventory/reportedSku
    group: inventory
    actions: [VIEW]

  - name: Inventory/inventoryDate
    group: inventory
    actions: [VIEW]

  - name: Inventory/unitOfMeasure
    group: inventory
    actions: [VIEW]

  - name: Inventory/id
    group: inventory-internal
    actions: [VIEW]

  - name: Inventory/originalId
    group: inventory
    actions: [VIEW]

  - name: Inventory/lineNumber
    group: inventory-internal
    actions: [VIEW]

    # data file

  - name: Inventory/dataFile
    group: inventory-data-file
    actions: [VIEW]

  - name: Inventory/dataFile/*
    group: inventory-internal
    actions: [VIEW]

  - name: Inventory/dataFile/loadDate
    group: inventory-data-file
    actions: [VIEW]

  - name: Inventory/dataFile/reportDate
    group: inventory-data-file
    actions: [VIEW]

  - name: Inventory/dataFile/id
    group: inventory-data-file
    actions: [VIEW]

  - name: Inventory/dataFile/fileName
    group: inventory-data-file
    actions: [VIEW]

  - name: Inventory/dataFile/recordCount
    group: inventory-data-file
    actions: [VIEW]

    # reporting partner

  - name: Inventory/reportingPartner
    group: inventory-reporting-partner
    actions: [VIEW]

  - name: Inventory/reportingPartner/*
    group: inventory-internal
    actions: [VIEW]

  - name: Inventory/reportingPartner/gsNumbers
    group: inventory-reporting-partner
    actions: [VIEW]

  - name: Inventory/reportingPartner/gsNumbers/value
    group: inventory-reporting-partner
    actions: [VIEW]

    # submission period

  - name: Inventory/submissionPeriod
    group: inventory-submission-period
    actions: [VIEW]

  - name: Inventory/submissionPeriod/*
    group: inventory-internal
    actions: [VIEW]

  - name: Inventory/submissionPeriod/expectedDate
    group: inventory-submission-period
    actions: [VIEW]

  - name: Inventory/submissionPeriod/periodStartDate
    group: inventory-submission-period
    actions: [VIEW]

  - name: Inventory/submissionPeriod/periodEndDate
    group: inventory-submission-period
    actions: [VIEW]

    # quantities

  - name: Inventory/inventoryQuantities
    group: inventory-quantity
    actions: [VIEW]

  - name: Inventory/inventoryQuantities/*
    group: inventory-internal
    actions: [VIEW]

  - name: Inventory/onHandQuantity
    group: inventory-quantity
    actions: [VIEW]

  - name: Inventory/onHandQuantity/*
    group: inventory-internal
    actions: [VIEW]

  - name: Inventory/onHandQuantity/value
    group: inventory-quantity
    actions: [VIEW]

  - name: Inventory/onOrderQuantity
    group: inventory-quantity
    actions: [VIEW]

  - name: Inventory/onOrderQuantity/*
    group: inventory-internal
    actions: [VIEW]

  - name: Inventory/onOrderQuantity/value
    group: inventory-quantity
    actions: [VIEW]

  - name: Inventory/committedQuantity
    group: inventory-quantity
    actions: [VIEW]

  - name: Inventory/committedQuantity/*
    group: inventory-internal
    actions: [VIEW]

  - name: Inventory/committedQuantity/value
    group: inventory-quantity
    actions: [VIEW]

  - name: Inventory/floatQuantity
    group: inventory-quantity
    actions: [VIEW]

  - name: Inventory/floatQuantity/*
    group: inventory-internal
    actions: [VIEW]

  - name: Inventory/floatQuantity/value
    group: inventory-quantity
    actions: [VIEW]

  - name: Inventory/backorderedQuantity
    group: inventory-quantity
    actions: [VIEW]

  - name: Inventory/backorderedQuantity/*
    group: inventory-internal
    actions: [VIEW]

  - name: Inventory/backorderedQuantity/value
    group: inventory-quantity
    actions: [VIEW]

  - name: Inventory/returnedQuantity
    group: inventory-quantity
    actions: [VIEW]

  - name: Inventory/returnedQuantity/*
    group: inventory-internal
    actions: [VIEW]

  - name: Inventory/returnedQuantity/value
    group: inventory-quantity
    actions: [VIEW]

  - name: Inventory/inTransitQuantity
    group: inventory-quantity
    actions: [VIEW]

  - name: Inventory/inTransitQuantity/*
    group: inventory-internal
    actions: [VIEW]

  - name: Inventory/inTransitQuantity/value
    group: inventory-quantity
    actions: [VIEW]

    # prices

  - name: Inventory/inventoryPrices
    group: inventory-price
    actions: [VIEW]

  - name: Inventory/inventoryPrices/*
    group: inventory-internal
    actions: [VIEW]

  - name: Inventory/unitPrice
    group: inventory-price
    actions: [VIEW]

  - name: Inventory/unitPrice/*
    group: inventory-internal
    actions: [VIEW]

  - name: Inventory/unitPrice/price
    group: inventory-price
    actions: [VIEW]

  - name: Inventory/unitPrice/fromCurrency
    group: inventory-price
    actions: [VIEW]

  - name: Inventory/unitPrice/fromCurrency/name
    group: inventory-price
    actions: [VIEW]

  - name: Inventory/unitPrice/toCurrency
    group: inventory-price
    actions: [VIEW]

  - name: Inventory/unitPrice/toCurrency/name
    group: inventory-price
    actions: [VIEW]

    ## Begin INV Dynamic Attrs

  - name: Inventory/dynamicAttrs
    group: inventory-dynamic-attrs
    actions: [VIEW]

  - name: Inventory/dynamicAttrs/*
    group: inventory-dynamic-attrs
    actions: [VIEW]

    ## End INV Dynamic Attrs

    ### End INV Fields

  # UI Resource for access to File Tab
  - name: FilesTab
    actions: [VIEW, UPDATE]

  ## Begin Partner

  - name: Partner
    group: reporting-partner
    actions: [VIEW]

  - name: Partner/*
    group: reporting-partner
    actions: [VIEW]

  ## End Partner

  # Begin File fields
  - name: DataFile
    group: file-management
    actions: [VIEW, UPDATE]

  - name: DataFile/sid
    group: file-management
    actions: [VIEW]

  - name: DataFile/loadDate
    group: file-management
    actions: [VIEW]

  - name: DataFile/reportDate
    group: file-management
    actions: [VIEW]

  - name: DataFile/fileName
    group: file-management
    actions: [VIEW]

  - name: DataFile/fileType
    group: file-management
    actions: [VIEW]

  - name: DataFile/dataType
    group: file-management
    actions: [VIEW]

  - name: DataFile/id
    group: file-management
    actions: [VIEW]

  - name: DataFile/fileSize
    group: file-management
    actions: [VIEW]

  - name: DataFile/source
    group: file-management
    actions: [VIEW]

  - name: DataFile/recordCount
    group: file-management
    actions: [VIEW]

  - name: DataFile/deletedLines
    group: file-management
    actions: [VIEW]

  - name: DataFile/download
    group: file-download
    actions: [VIEW]

  - name: DataFile/validationDownload
    group: file-validation-download
    actions: [VIEW]

  - name: DataFile/upload
    group: file-upload
    actions: [VIEW]

  - name: DataFile/uploadDataTypes
    group: file-upload
    actions: [VIEW]

  - name: DataFile/uploadFileTypes
    group: file-upload
    actions: [VIEW]

  - name: DataFile/reportingPartner
    group: file-reporting-partner
    actions: [VIEW]

  - name: DataFile/reportingPartner/*
    group: file-reporting-partner
    actions: [VIEW]

  - name: DataFile/reportingPartner/partnerOverlayView
    group: file-reporting-partner
    actions: [VIEW]

  - name: DataFile/reportingPartner/partnerOverlayView/*
    group: file-reporting-partner
    actions: [VIEW]

  - name: DataFile/dataFileState
    group: file-data-file-state
    actions: [VIEW]

  - name: DataFile/dataFileState/*
    group: file-data-file-state
    actions: [VIEW]

  - name: DataFile/dataFileState/sid
    group: file-data-file-state
    actions: [VIEW]

  - name: DataFile/dataFileState/createDate
    group: file-data-file-state
    actions: [VIEW]

  - name: DataFile/dataFileState/updateDate
    group: file-data-file-state
    actions: [VIEW]

  - name: DataFile/parserAttempt
    group: file-parser-attempt
    actions: [VIEW]

  - name: DataFile/parserAttempt/*
    group: file-parser-attempt
    actions: [VIEW]

  # End of File fields
  
  # UI Resource for access to Submission Schedule
  - name: SubmissionTrackingTab
    actions: [VIEW, UPDATE]

  - name: SubmissionResultsTab
    actions: [VIEW, UPDATE]

  # Begin Submission Schedule 
  - name: SubmissionSchedule
    group: submission-schedule
    actions: [VIEW, UPDATE]

  - name: SubmissionSchedule/sid
    group: submission-schedule
    actions: [VIEW]

  - name: SubmissionSchedule/createDate
    group: submission-schedule
    actions: [VIEW]

  - name: SubmissionSchedule/updateDate
    group: submission-schedule
    actions: [VIEW]

  - name: SubmissionSchedule/name
    group: submission-schedule
    actions: [VIEW]

  - name: SubmissionSchedule/reportingPartner
    group: ss-reporting-partner
    actions: [VIEW]

  - name: SubmissionSchedule/reportingPartner/*
    group: ss-reporting-partner
    actions: [VIEW]

  - name: SubmissionSchedule/reportingPartner/partnerOverlayView
    group: ss-reporting-partner
    actions: [VIEW]

  - name: SubmissionSchedule/reportingPartner/partnerOverlayView/*
    group: ss-reporting-partner
    actions: [VIEW]

  - name: SubmissionSchedule/dataType
    group: ss-data-type
    actions: [VIEW]

  - name: SubmissionSchedule/dataType/*
    group: ss-data-type
    actions: [VIEW]

  - name: SubmissionSchedule/periodRule
    group: submission-schedule
    actions: [VIEW]

  - name: SubmissionSchedule/expectedDay
    group: submission-schedule
    actions: [VIEW]

  - name: SubmissionSchedule/startDate
    group: submission-schedule
    actions: [VIEW]

  - name: SubmissionSchedule/endDate
    group: submission-schedule
    actions: [VIEW]

  - name: SubmissionSchedule/isInPeriodReporter
    group: submission-schedule
    actions: [VIEW]

  - name: SubmissionSchedule/weekOfMonth
    group: submission-schedule
    actions: [VIEW]

  - name: SubmissionSchedule/monthOfQuarter
    group: submission-schedule
    actions: [VIEW]

  - name: SubmissionSchedule/workingDays
    group: submission-schedule
    actions: [VIEW]

  # End Submission Schedule 

  # Begin Submission Schedule Notification
  - name: SubmissionScheduleNotification
    group: submission-schedule-notification
    actions: [VIEW]
  
  - name: SubmissionScheduleNotification/*
    group: submission-schedule-notification
    actions: [VIEW]

  - name: SubmissionScheduleNotification/notificationType
    group: submission-schedule-notification
    actions: [VIEW]

  - name: SubmissionScheduleNotification/notificationType/*
    group: submission-schedule-notification
    actions: [VIEW]

  - name: SubmissionScheduleNotification/serviceUser
    group: submission-schedule-notification
    actions: [VIEW]

  - name: SubmissionScheduleNotification/serviceUser/*
    group: submission-schedule-notification
    actions: [VIEW]

  # END Submission Schedule Notification

  # Begin Submission Period
  - name: SubmissionPeriod
    group: submission-period-update
    actions: [VIEW, UPDATE]

  - name: SubmissionPeriod/sid
    group: submission-period
    actions: [VIEW]

  - name: SubmissionPeriod/expectedDate
    group: submission-period
    actions: [VIEW]

  - name: SubmissionPeriod/periodStartDate
    group: submission-period
    actions: [VIEW]

  - name: SubmissionPeriod/periodEndDate
    group: submission-period
    actions: [VIEW]

  - name: SubmissionPeriod/createDate
    group: submission-period
    actions: [VIEW]

  - name: SubmissionPeriod/updateDate
    group: submission-period
    actions: [VIEW]

  - name: SubmissionPeriod/noData
    group: submission-period-update
    actions: [VIEW, UPDATE]

  - name: SubmissionPeriod/noDataReason
    group: submission-period-update
    actions: [VIEW, UPDATE]

  - name: SubmissionPeriod/noDataCreateDate
    group: submission-period-update
    actions: [VIEW, UPDATE]

  - name: SubmissionPeriod/onTimeOverride
    group: submission-period
    actions: [VIEW]

  - name: SubmissionPeriod/expectedDay
    group: submission-period
    actions: [VIEW]

  - name: SubmissionPeriod/workingDays
    group: submission-period
    actions: [VIEW]

  - name: SubmissionPeriod/isInPeriodReporter
    group: submission-period
    actions: [VIEW]

  - name: SubmissionPeriod/trackingLevel
    group: submission-period
    actions: [VIEW]

  - name: SubmissionPeriod/status
    group: submission-period
    actions: [VIEW]

  - name: SubmissionPeriod/reportedFlag
    group: submission-period
    actions: [VIEW]

  - name: SubmissionPeriod/fileIds
    group: submission-period
    actions: [VIEW]

  - name: SubmissionPeriod/firstFileName
    group: submission-period
    actions: [VIEW]

  - name: SubmissionPeriod/firstFileCreateDate
    group: submission-period
    actions: [VIEW]

  - name: SubmissionPeriod/firstFileId
    group: submission-period
    actions: [VIEW]

  - name: SubmissionPeriod/deleted
    group: submission-period
    actions: [VIEW]

  - name: SubmissionPeriod/noDataServiceUser
    group: submission-period-update
    actions: [VIEW, UPDATE]

  - name: SubmissionPeriod/noDataServiceUser/sid
    group: sp-no-data-user
    actions: [VIEW]

  - name: SubmissionPeriod/noDataServiceUser/firstName
    group: sp-no-data-user
    actions: [VIEW]

  - name: SubmissionPeriod/noDataServiceUser/lastName
    group: sp-no-data-user
    actions: [VIEW]

  - name: SubmissionPeriod/noDataServiceUser/email
    group: sp-no-data-user
    actions: [VIEW]

  - name: SubmissionPeriod/submissionPeriodLineItemView
    group: submission-period
    actions: [VIEW]

  - name: SubmissionPeriod/submissionPeriodLineItemView/*
    group: submission-period
    actions: [VIEW]

  - name: SubmissionPeriod/dataFileSummaryInfo
    group: submission-period
    actions: [VIEW]

  - name: SubmissionPeriod/dataFileSummaryInfo/*
    group: submission-period
    actions: [VIEW]
    
  - name: SubmissionPeriod/submissionSchedule
    group: submission-period
    actions: [VIEW]
    
  - name: SubmissionPeriod/submissionSchedule/sid
    group: submission-period
    actions: [VIEW]
    
  - name: SubmissionPeriod/submissionSchedule/name
    group: submission-period
    actions: [VIEW]
    
  - name: SubmissionPeriod/submissionSchedule/periodRule
    group: submission-period
    actions: [VIEW]

  - name: SubmissionPeriod/submissionSchedule/reportingPartner
    group: sp-reporting-partner
    actions: [VIEW]

  - name: SubmissionPeriod/submissionSchedule/reportingPartner/*
    group: sp-reporting-partner
    actions: [VIEW]

  - name: SubmissionPeriod/submissionSchedule/reportingPartner/partnerOverlayView
    group: sp-reporting-partner
    actions: [VIEW]

  - name: SubmissionPeriod/submissionSchedule/reportingPartner/partnerOverlayView/*
    group: sp-reporting-partner
    actions: [VIEW]

  - name: SubmissionPeriod/submissionSchedule/dataType
    group: sp-data-type
    actions: [VIEW]

  - name: SubmissionPeriod/submissionSchedule/dataType/*
    group: sp-data-type
    actions: [VIEW]

  # End Submission Period

  # Begin Export Request

  - name: ExportRequest
    group: export
    actions: [VIEW, UPDATE]

  - name: ExportRequest/*
    group: export
    actions: [VIEW, UPDATE]

  # End Export Request

  ### Begin Base resources

  - name: About
    group: about
    actions: [VIEW]

  - name: About/*
    group: about
    actions: [VIEW]

  - name: UserEvent
    group: user-event
    actions: [VIEW, UPDATE]

  - name: UserEvent/*
    group: user-event
    actions: [VIEW, UPDATE]

  - name: ObjectLock
    group: object-lock
    actions: [VIEW, UPDATE]

  - name: ObjectLock/*
    group: object-lock
    actions: [VIEW, UPDATE]

  - name: ObjectLockResponse
    group: object-lock-response
    actions: [VIEW]

  - name: ObjectLockResponse/*
    group: object-lock-response
    actions: [VIEW]

  - name: MutationResponse
    group: mutation-response
    actions: [VIEW]

  - name: MutationResponse/*
    group: mutation-response
    actions: [VIEW]

  - name: DynamicAttrMetadata
    group: attr-metadata
    actions: [VIEW]

  - name: DynamicAttrMetadata/*
    group: attr-metadata
    actions: [VIEW]
    

  ### End Base resources

  ### Begin mutation resources

  - name: Product/mutation/*
    group: product-update
    actions: [UPDATE]

  - name: Sales/mutation/*
    group: sales-update
    actions: [UPDATE]

  - name: Inventory/mutation/*
    group: inventory-update
    actions: [UPDATE]

  - name: ExportRequest/mutation/*
    group: export
    actions: [UPDATE]

  - name: SubmissionPeriod/mutation/*
    group: submission-period-mutation
    actions: [UPDATE]

    ### End mutation resources

    ### Begin Customer Resources

  - name: INT
    actions: [VIEW]

  - name: ACS
    actions: [VIEW]

  - name: CAMB
    actions: [VIEW]

  - name: CYBERDYNE
    actions: [VIEW]

  - name: COR
    actions: [VIEW]

  - name: INT_CCD
    actions: [VIEW]

  - name: ACS_CCD
    actions: [VIEW]

  - name: CAMB_CCD
    actions: [VIEW]

  - name: QCOM_CCD
    actions: [VIEW]

  - name: COR_CCD
    actions: [VIEW]

    ### End Customer Resources

# Common permissions for all tenants
permissions:

  - name: BasicViewUpdate
    displayName: Background Permissions
    description: Every User needs this permission
    resource-actions:
      - about:[VIEW]
      - user-event:[VIEW, UPDATE]
      - object-lock:[VIEW, UPDATE]
      - object-lock-response:[VIEW]
      - mutation-response:[VIEW]
      - attr-metadata:[VIEW]

  - name: KpiView
    displayName: KPI Tab
    description: KPI Permission Set
    resource-actions:
      - ProductKpiTab:[VIEW]

  - name: SSKpiFields
    displayName: Submission KPI Fields
    description: Submission KPI Fields Permission Set
    resource-actions:
      - ssKpi:[VIEW]

  - name: FilesKpiFields
    displayName: Files KPI Fields
    description: Files KPI Fields Permission Set
    resource-actions:
      - filesKpi:[VIEW]

  - name: FileTab
    displayName: File Tab
    description: File Permission Set
    resource-actions:
      - FilesTab:[VIEW]

  - name: FileUploadPartner
    displayName: File Upload for Partner
    description: File Upload Permission Set
    resource-actions:
      - DataFile:[VIEW, UPDATE] 
      - file-upload:[VIEW]     

  - name: FileUpload
    displayName: File Upload 
    description: File Upload Permission Set
    resource-actions:
      - DataFile:[VIEW]
      - file-upload:[VIEW]
      - reporting-partner:[VIEW]

  - name: FileDownload
    displayName: File Download
    description: File Download Permission Set
    resource-actions:
      - DataFile:[VIEW]
      - file-download:[VIEW]
      - file-validation-download:[VIEW]

  - name: SubmissionTab
    displayName: Submission Tab
    description: File Permission Set
    resource-actions:
      - SubmissionTrackingTab:[VIEW]
      - SubmissionResultsTab:[VIEW]

  - name: FileManufactureView
    displayName: File Admin View
    description: File Admin Permission Set
    resource-actions:
      - file-management:[VIEW]
      - file-reporting-partner:[VIEW]
      - file-data-file-state:[VIEW]
      - file-parser-attempt:[VIEW]

  - name: FilePartnerView
    displayName: File Partner View
    description: File Partner Permission Set
    resource-actions:
      - file-management:[VIEW]
      - file-data-file-state:[VIEW]
      - file-parser-attempt:[VIEW]

  - name: SubmissionManufactureView
    displayName: Submission Admin View
    description: Submission Full Permission Set
    resource-actions:
      - submission-schedule:[VIEW]
      - submission-schedule-notification:[VIEW]
      - ss-reporting-partner:[VIEW]
      - ss-data-type:[VIEW]
      - submission-period:[VIEW]
      - sp-reporting-partner:[VIEW]
      - sp-data-type:[VIEW]
      - sp-no-data-user:[VIEW]
      - submission-period-update:[VIEW]

  - name: SubmissionPartnerView
    displayName: Submission Partner View
    description: Submission Full Permission Set
    resource-actions:
      - submission-schedule:[VIEW]
      - submission-schedule-notification:[VIEW]
      - ss-data-type:[VIEW]
      - submission-period:[VIEW]
      - sp-data-type:[VIEW]
      - sp-no-data-user:[VIEW]
      - submission-period-update:[VIEW]

  - name: SubmissionPartnerUpdate
    displayName: Submission Partner Update
    description: Submission Update Permission Set
    resource-actions:
      - submission-period-update:[UPDATE]
      - submission-period-mutation:[UPDATE]

  - name: SubmissionUpdate
    displayName: Submission Update 
    description: Submission Update Permission Set
    resource-actions:
      - submission-period-update:[UPDATE]
      - submission-period-mutation:[UPDATE]
export const SubmissionDef = `
  type Query {
    submissionPeriods(
      offset: Float, 
      limit: Float,
      filters: SubmissionPeriodFilters,
      sort: SubmissionPeriodSort
    ): [SubmissionPeriod]
    submissionSchedules(
      offset: Float, 
      limit: Float,
      filters: SubmissionScheduleFilters, 
      sort: SubmissionScheduleSort
    ): [SubmissionSchedule]
    submissionScheduleNotifications(
      submissionScheduleSid: ID,
      offset: Float,
      limit: Float,
      filters: SubmissionScheduleNotificationFilters,
      sort: SubmissionScheduleNotificationSort
    ): [SubmissionScheduleNotification]
  }

  type Mutation {
    markNoData(data: [NoDataInput]): [MutationResponse] @auth(object: SubmissionPeriod)
  }

  type SubmissionPeriod {
    sid: ID
    createDate: Date
    updateDate: Date
    customerSid: ID
    expectedDate: Date
    periodStartDate: Date
    periodEndDate: Date
    noData: Boolean
    noDataReason: String
    noDataCreateDate: Date
    onTimeOverride: Boolean
    expectedDay: String
    workingDays: String
    isInPeriodReporter: Float
    trackingLevel: String
    submissionSchedule: SubmissionSchedule
    status: String
    reportedFlag: Boolean
    numberOfFiles: Float
    dataFileSummaryInfo: DataFileSummaryInfo
    submissionPeriodInfoView: SubmissionPeriodInfoView
    submissionPeriodLineItemView: SubmissionPeriodLineItemView
    noDataServiceUser: ServiceUser
  }

  type SubmissionPeriodLineItemView {
    salesLineItemCount: Float
    invLineItemCount: Float
    earliestFileSubmissionDate: Date
  }

  type SubmissionPeriodInfoView {
    numberOfInventoryLines: Float
    numberOfPOSLines:Float
    fileName: String
    fileId: Float
  }

  type DataFileSummaryInfo{
    numberOfPOSLines: Float
    numberOfInventoryLines: Float
    submissionPeriodSid: Float
  }
  
  type SubmissionSchedule {
    sid: ID
    createDate: Date
    updateDate: Date
    customerSid: ID
    dataType: DataType    
    reportingPartner: Partner
    periodRule: String
    name: String
    startDate: Date
    endDate: Date
    expectedDay: String
    workingDays: String
    isInPeriodReporter: Boolean
    weekOfMonth: Float
    monthOfQuarter: Float
  }

  type DataType {
    sid: ID
    createDate: Date
    updateDate: Date
    type: String
  }

  type SubmissionScheduleNotification {
    sid: ID
    createDate: Date
    updateDate: Date
    customerSid: ID
    submissionScheduleSid: ID
    notificationType: NotificationType
    serviceUser: ServiceUser
  }

  enum NotificationType {
    PARSE_SUCCESS
    LATE
    PARSE_FAIL
    EXPECTED
  }

  input SubmissionPeriodFilters {
    sid: IDFilter
    createDate: DateFilter
    updateDate: DateFilter
    customerSid: IDFilter
    expectedDate: DateFilter
    periodStartDate: DateFilter
    periodEndDate: DateFilter
    submissionSchedule: SubmissionScheduleFilters
    status: StringFilter
    reportedFlag: BooleanFilter
    submissionPeriodLineItemView: SubmissionPeriodLineItemViewFilter
    numberOfFiles: NumberFilter
  }
  
  input SubmissionPeriodLineItemViewFilter {
    salesLineItemCount: NumberFilter
    invLineItemCount: NumberFilter
    earliestFileSubmissionDate: DateFilter
  }

  input SubmissionScheduleFilters {
    sid: IDFilter
    createDate: DateFilter
    updateDate: DateFilter
    customerSid: IDFilter
    reportingPartner: PartnerFilter
    name: StringFilter
    dataType: DataTypeFilter
    periodRule: StringFilter
    expectedDay: StringFilter
    workingDays: StringFilter
    startDate: DateFilter
    endDate: DateFilter
    isInPeriodReporter: BooleanFilter
    weekOfMonth: NumberFilter
    monthOfQuarter: NumberFilter
  }

  input DataTypeFilter {
    sid: IDFilter
    createDate: DateFilter
    updateDate: DateFilter
    type: StringFilter
  }

  input SubmissionScheduleNotificationFilters {
    sid: IDFilter
    createDate: DateFilter
    updateDate: DateFilter
    customerSid: IDFilter
    submissionScheduleSid: IDFilter
    notificationType: StringFilter
    serviceUser: ServiceUserFilters
  }

  input SubmissionPeriodSort {
    sid: SortOption
    createDate: SortOption
    updateDate: SortOption
    expectedDate: SortOption
    periodStartDate: SortOption
    periodEndDate: SortOption
    submissionSchedule: SubmissionScheduleSort
    status: SortOption
    reportedFlag: SortOption
    submissionPeriodLineItemView: SubmissionPeriodLineItemViewSort
    numberOfFiles: SortOption
  }
  
  input SubmissionPeriodLineItemViewSort {
    salesLineItemCount: SortOption
    invLineItemCount: SortOption
    earliestFileSubmissionDate: SortOption
  }

  input SubmissionScheduleSort {
    sid: SortOption
    createDate: SortOption
    updateDate: SortOption
    customerSid: SortOption
    dataType: DataTypeSort
    reportingPartner: PartnerSort
    periodRule: SortOption
    name: SortOption
    startDate: SortOption
    endDate: SortOption
    expectedDay: SortOption
    workingDays: SortOption
    isInPeriodReporter: SortOption
    weekOfMonth: SortOption
    monthOfQuarter: SortOption
  }

  input DataTypeSort {
    sid: SortOption
    createDate: SortOption
    updateDate: SortOption
    type: SortOption
  }

  input SubmissionScheduleNotificationSort {
    sid: SortOption
    createDate: SortOption
    updateDate: SortOption
    notificationType: SortOption
    serviceUser: ServiceUserSort
  }

  input NoDataInput {
    sid: ID!
    noDataReason: String
  }
`;
import { Inject, Service } from 'typedi';
import { FindOptions } from '../base/FindOptions';
import { PartnerService } from '../partner/PartnerService';
import { SubmissionPeriod } from './SubmissionPeriod';
import { SubmissionPeriodInput } from './SubmissionPeriodInput';
import { Operator } from '../base/filters/Operator';
import { ServiceError } from '../base/ServiceError';
import { User } from '../user/User';
import { AuditEventService } from '../event/AuditEventService';
import { CustomerDomainEntityService } from '../base/CustomerDomainEntityService';
import { SubmissionScheduleAuditService } from './SubmissionScheduleAuditService';
import { AuditEvent } from '../event/AuditEvent';
import { ServiceUserService } from '../user/ServiceUserService';
import { AuditTypeService } from '../event/AuditTypeService';
import { SubmissionScheduleAudit } from './SubmissionScheduleAudit';
import { AuditType } from '../event/AuditType';

export const NO_DATA_ACTION_TYPE = 'SubmissionScheduleNoDataReported';

@Service()
export class SubmissionPeriodService extends CustomerDomainEntityService<SubmissionPeriod> {
  @Inject()
  protected partnerService: PartnerService;

  @Inject()
  protected auditEventService: AuditEventService;

  @Inject()
  protected submissionScheduleAuditService: SubmissionScheduleAuditService;

  @Inject()
  protected serviceUserService: ServiceUserService;

  @Inject()
  protected auditTypeService: AuditTypeService;

  constructor() {
    super(SubmissionPeriod);
  }

  getServiceName() {
    return 'SubmissionPeriod';
  }

  async findSubmissionPeriods(
    customerId: string,
    partnerId: string,
    options: FindOptions = new FindOptions()
  ): Promise<SubmissionPeriod[]> {
    const customer = await this.customerService.findOneById(customerId);
    const partner = await this.partnerService.findOneById(partnerId);
    const { offset, limit, filters = {}, sort } = options;

    // return empty array if customer or partner is invalid
    if (!customer || (!partner && !PartnerService.isAll(partnerId))) {
      console.error(
        'Customer ' + customerId + ' or partner ' + partnerId + ' are invalid'
      );
      return [];
    }

    const query = this.repository
      .createQueryBuilder('sp')
      .innerJoinAndSelect(
        'sp.submissionSchedule',
        'ss',
        '"sp"."CUSTOMER_SID" = "ss"."CUSTOMER_SID"'
      )
      .innerJoinAndSelect('ss.dataType', 'dt')
      .innerJoinAndSelect('ss.reportingPartner', 'rp')
      .innerJoinAndSelect('rp.partnerOverlayView', 'csr')
      .leftJoinAndSelect(
        'sp.submissionPeriodLineItemView',
        'spli',
        '"sp"."CUSTOMER_SID" = "spli"."CUSTOMER_SID"'
      )
      .leftJoinAndSelect(
        'sp.dataFileSummaryInfo',
        'dfsi',
        '"sp"."CUSTOMER_SID" = "dfsi"."CUSTOMER_SID"'
      )
      .offset(offset)
      .limit(limit);

    this.buildWhere(filters, query);

    query.andWhere(`"sp"."CUSTOMER_SID" = ${customer.sid}`)
      .andWhere(`"sp"."DELETED" = 0`)
      .andWhere(`"csr"."CUSTOMER_SID" = ${customer.sid}`);

    if (partner) {
      query.andWhere('"ss"."REPORTING_PARTNER_SID" = ' + partner.sid);
    }
    this.addOrderBys(query, sort ?? {});
    let periods: SubmissionPeriod[] = await query.getMany();
    periods = periods.map((period) => {
      if (period.fileIds) {
        period.firstFileId = period.fileIds.split(',')[0];
      }
      return period;
    });

    periods = await this.loadFirstFileFields(customer.sid, periods);

    return periods;
  }

  async loadFirstFileFields(
    customerSid: number,
    periods: SubmissionPeriod[]
  ): Promise<SubmissionPeriod[]> {

    if (periods.length === 0) return periods;

    // construct SQL
    const sql =
      ` select ID "id", FILE_NAME "file_name", CREATE_DATE "create_date" 
        from data_file 
        where customer_sid = ${customerSid} and id in (:ids) `;

    // execute SQL
    let rows = new Map();

    for (let i = 0; i < periods.length; i += 1000) {
      let subSet = periods.slice(i, i + 1000);
      let dfIds = [];
      for (let j = 0; j < subSet.length; j++) {
        if (subSet[j].firstFileId) {
          dfIds.push(`'${subSet[j].firstFileId}'`);
        }
      }
      if (dfIds.length === 0) continue;
      //not a param to avoid bind var peaking
      let inListSql = sql.replace(':ids', dfIds.join(','));

      let results = await this.repository.query(inListSql);
      results.map((r) => {
        rows.set(r.id, r);
      });
    }
    // map SQL result
    return periods.map((period) => {
      if (period.firstFileId) {
        period.firstFileName = rows.get(period.firstFileId).file_name;
        period.firstFileCreateDate = rows.get(period.firstFileId).create_date;
      }
      return period;
    });
  }

  async markNoData(
    customerId: string,
    user: User,
    data: Partial<SubmissionPeriodInput>[]
  ): Promise<ServiceError[]> {
    let sids: number[] = data.map((input: SubmissionPeriodInput) => {
      return input.sid;
    });

    const options: FindOptions = {
      offset: 0,
      limit: 1000,
      filters: {
        sid: {
          operator: Operator.IN,
          values: sids
        }
      }
    };

    const submissionPeriods = await this.findSubmissionPeriods(
      customerId,
      user.partnerId,
      options
    );

    if (submissionPeriods.length <= 0) {
      throw new Error(`Customer ${customerId} or partner ${user.partnerId} are invalid`);
    }

    const serviceUser = await this.serviceUserService.findByLogin(user.nucleusUsername);
    if (!serviceUser) {
      throw new Error(`Service user not found for login ${user.id}`);
    }

    const auditType = await this.auditTypeService.findOneByName(
      NO_DATA_ACTION_TYPE
    );

    let errors: Array<ServiceError> = [];
    let submissionPeriodMap: Map<Number, SubmissionPeriod> = new Map();
    let validInput: Partial<SubmissionPeriodInput>[] = [];

    submissionPeriods.forEach((submissionPeriod) => {
      submissionPeriodMap.set(Number(submissionPeriod.sid), submissionPeriod);
    });

    data.forEach((submissionPeriodInput) => {
      submissionPeriodInput.noData = true;
      submissionPeriodInput.noDataCreateDate = new Date();
      submissionPeriodInput.noDataServiceUserSid = serviceUser.sid;

      let submissionPeriod = submissionPeriodMap.get(Number(submissionPeriodInput.sid))
      let err = submissionPeriod ? this.validateForMarkNoData(submissionPeriod) : null;
      if (submissionPeriod && !err) validInput.push(submissionPeriodInput);
      errors.push(err);
    });

    if (validInput.length === 0) return errors;

    const updateServiceErrors: Array<ServiceError> = await this.updateSubmissionPeriods(
      customerId,
      user,
      validInput,
      auditType
    );

    let dataIndex = 0;
    let validDataIndex = 0;
    data.forEach((submissionPeriodInput) => {
      if (validDataIndex < validInput.length && submissionPeriodInput.sid == validInput[validDataIndex].sid) {
        if (!errors[dataIndex]) {
          errors[dataIndex++] = updateServiceErrors[validDataIndex++];
        }
      } else {
        dataIndex++;
      }
    });

    return errors;
  }

  validateForMarkNoData(submissionPeriod: SubmissionPeriod): ServiceError | null {
    let comparisonDate: Date = new Date();
    comparisonDate.setDate(comparisonDate.getDate() - 31);
    if (submissionPeriod.reportedFlag) {
      return new ServiceError('REPORTED_DATA_ERROR', 'Submission Period already has reported data, so No-Data-To-Report is not applicable.');
    } else if (submissionPeriod.noDataReason != null) {
      return new ServiceError('ALREAD_MARKED_NO_DATA_ERROR', 'Submission Period is already marked as No-Data-To-Report.');
    } else if (submissionPeriod.fileIds) {
      return new ServiceError('LINE_COUNT_ERROR', 'Submission Period already has line items count, so No-Data-To-Report is not applicable.');
    } else if (submissionPeriod.periodEndDate.getTime() < comparisonDate.getTime()) {
      return new ServiceError('GRACE_PERIOD_ERROR', 'Submission Period is beyond the grace period to mark as No-Data-To-Report.');
    }
    return null;
  }

  async updateSubmissionPeriods(
    customerId: string,
    user: User,
    data: Partial<SubmissionPeriodInput>[],
    auditType?: AuditType,
  ): Promise<ServiceError[]> {
    const customer = await this.customerService.findOneById(customerId);
    const partner = await this.partnerService.findOneById(user.partnerId);
    const serviceUser = await this.serviceUserService.findByLogin(user.nucleusUsername);

    if (!serviceUser || serviceUser.sid === 0) {
      throw new Error(`Service user not found for login ${user.id}`);
    }

    let sids: number[] = data.map((input: SubmissionPeriodInput) => {
      return input.sid;
    });

    const options: FindOptions = {
      offset: 0,
      limit: 1000,
      filters: {
        sid: {
          operator: Operator.IN,
          values: sids
        }
      }
    };

    const submissionPeriods = await this.findSubmissionPeriods(
      customerId,
      user.partnerId,
      options
    );

    let submissionPeriodMap = new Map<number, SubmissionPeriod>();
    submissionPeriods.map((submissionPeriod) => {
      submissionPeriodMap.set(Number(submissionPeriod.sid), submissionPeriod);
    });

    return await Promise.all(
      data.map(async (submissionPeriodInput) => {
        try {
          const submissionPeriod = submissionPeriodMap.get(
            Number(submissionPeriodInput.sid)
          );
          if (submissionPeriod) {
            await this.update(
              submissionPeriod.sid,
              Object.assign({}, submissionPeriodInput)
            );
          }

          if (auditType) {
            let auditEvent = new AuditEvent();
            auditEvent = await this.auditEventService.createAuditEvent(
              Object.assign({}, auditEvent, {
                serviceUserSid: serviceUser.sid,
                eventTimeStamp: new Date(),
                customerSid: customer.sid,
                reportingPartnerSid: partner ? partner.sid : null,
                auditTypeSid: auditType.sid,
                parentSid: null,
                createDate: new Date()
              })
            );

            const submissionScheduleAudit = new SubmissionScheduleAudit();
            await this.submissionScheduleAuditService.createSubmissionScheduleAudit(
              Object.assign({}, submissionScheduleAudit, {
                submissionPeriodSid: submissionPeriod.sid,
                submissionScheduleSid: submissionPeriod.submissionScheduleSid,
                customerSid: customer.sid,
                details: null,
                auditEventSid: auditEvent.sid,
                createDate: new Date()
              })
            );
          }

          return null;
        } catch (err) {
          console.log(err);
          return new ServiceError(
            'SUBMISSION_PERIOD_ERR',
            `Submission period could not be updated for : ${submissionPeriodInput.sid}`
          );
        }
      })
    );
  }
}
import { ViewEntity, ViewColumn } from 'typeorm';

@ViewEntity({
  name: 'SUBMISSION_PERIOD_INFO_VIEW',
  expression: `
    SELECT
      ss1.SID AS submissionScheduleId,
      df.ID AS fileId,
      df.FILE_NAME AS fileName,
      df.CREATE_DATE AS fileCreateDate,
      dfsi.NUM_SLIS AS numberOfPOSLines,
      dfsi.NUM_ILIS AS numberOfInventoryLines
    FROM
      SUBMISSION_SCHEDULE ss1
      LEFT JOIN DATA_FILE_SUMMARY_INFO dfsi ON dfsi.SUBMISSION_PERIOD_SID = :sid AND dfsi.CUSTOMER_SID = :cs
      LEFT JOIN DATA_TYPE dt1 ON ss1.DATA_TYPE_SID = dt1.SID
      LEFT JOIN DATA_FILE df ON dfsi.CUSTOMER_SID = df.CUSTOMER_SID AND dfsi.DATA_FILE_SID = df.SID
                              AND df.DELETED = 0 AND df.DATA_TYPE = dt1.TYPE
    WHERE
      ss1.SID = :spssd AND ss1.CUSTOMER_SID = :cs AND df.ID IS NOT NULL
  `,
})
export class SubmissionPeriodInfoView {
  @ViewColumn()
  submissionScheduleId: number;

  @ViewColumn()
  fileId: number;

  @ViewColumn()
  fileName: string;

  @ViewColumn()
  fileCreateDate: Date;

  @ViewColumn()
  numberOfPOSLines: number;

  @ViewColumn()
  numberOfInventoryLines: number;
}
import { Entity, Column, JoinColumn, OneToOne, VirtualColumn, OneToMany } from 'typeorm';
import { CustomerDomainEntity } from '../base/CustomerDomainEntity';
import {
  returnsSubmissionPeriodLineItemView,
  SubmissionPeriodLineItemView
} from './SubmissionPeriodLineItemView';
import {
  reportedFlagSql,
  statusSql,
  fileIdsSql,
  filesCountSql,
  filesDataSql
} from './SubmissionPeriodSql';
import {
  returnsSubmissionSchedule,
  SubmissionSchedule
} from './SubmissionSchedule';
import { ServiceUser, returnsServiceUser } from '../user/ServiceUser';
import { DataFileSummaryInfo, returnsDataFileSummaryInfo } from '../datafile/DataFileSummaryInfo';
import { SubmissionPeriodInfoView } from './SubmissionPeriodInfoView';


export const returnsSubmissionPeriod = () => SubmissionPeriod;
export const dataFileSummaryInfoInverseSide = (dataFileSummaryInfo) =>
  dataFileSummaryInfo.submissionPeriod;

@Entity({ name: 'SUBMISSION_PERIOD' })
export class SubmissionPeriod extends CustomerDomainEntity {
  @Column({ name: 'EXPECTED_DATE' })
  expectedDate: Date;

  @Column({ name: 'PERIOD_START_DATE' })
  periodStartDate: Date;

  @Column({ name: 'PERIOD_END_DATE' })
  periodEndDate: Date;

  @Column({ name: 'SUBMISSION_SCHEDULE_SID', select: false })
  submissionScheduleSid: number;

  @Column({ name: 'ON_TIME_OVERRIDE' })
  onTimeOverride: boolean;

  @Column({ name: 'NO_DATA' })
  noData: boolean;

  @Column({ name: 'NO_DATA_REASON' })
  noDataReason: string;

  @Column({ name: 'NO_DATA_CREATE_DATE' })
  noDataCreateDate: Date;

  @Column({ name: 'NO_DATA_SERVICE_USER_SID', select: false })
  noDataServiceUserSid: number;

  @OneToOne(returnsServiceUser)
  @JoinColumn({ name: 'NO_DATA_SERVICE_USER_SID' })
  noDataServiceUser: Promise<ServiceUser>;

  @Column({ name: 'TRACKING_LEVEL' })
  trackingLevel: string;

  @Column({ name: 'EXPECTED_DAY' })
  expectedDay: number;

  @Column({ name: 'WORKING_DAYS' })
  workingDays: string;

  @Column({ name: 'IS_IN_PERIOD_REPORTER' })
  isInPeriodReporter: number;

  @Column({ name: 'DELETED' })
  deleted: boolean;

  @OneToOne(returnsSubmissionSchedule)
  @JoinColumn({ name: 'SUBMISSION_SCHEDULE_SID' })
  submissionSchedule?: Promise<SubmissionSchedule>;

  @VirtualColumn({ query: statusSql })
  status?: string;

  @VirtualColumn({ query: reportedFlagSql })
  reportedFlag: boolean;

  @VirtualColumn( {query : fileIdsSql} )
  fileIds?: string;

  firstFileId?: string;

  firstFileName?: string;

  firstFileCreateDate?: Date;

  @VirtualColumn( {query : filesCountSql} )
  numberOfFiles?: number;

  @OneToMany(() => SubmissionPeriodInfoView, submissionPeriodInfoView => submissionPeriodInfoView.submissionScheduleId)
  submissionPeriodInfoView?: SubmissionPeriodInfoView[];

  @OneToOne(returnsDataFileSummaryInfo)
  @JoinColumn({ name: 'SID', referencedColumnName: 'submissionPeriodSid' })
  dataFileSummaryInfo?: Promise<DataFileSummaryInfo>;

  @OneToOne(returnsSubmissionPeriodLineItemView)
  @JoinColumn({ name: 'SID', referencedColumnName: 'submissionPeriodSid' })
  submissionPeriodLineItemView?: Promise<SubmissionPeriodLineItemView>;

}
import { DomainEntityService } from '../base/DomainEntityService';
import { Inventory } from './Inventory';
import { Service, Inject } from 'typedi';
import { FindOptions } from '../base/FindOptions';
import { Equal, In } from 'typeorm';
import { ConfigurationService } from '../configuration/ConfigurationService';
import { CustomerService } from '../customer/CustomerService';
import { PartnerService } from '../partner/PartnerService';
import { DynamicAttrsService } from '../attribute/DynamicAttrsService';
import { DataFileService } from '../datafile/DataFileService';
import { SubmissionPeriodService } from '../submission/SubmissionPeriodService';
import { InventoryQuantityService } from './InventoryQuantityService';
import { InventoryPriceService } from './InventoryPriceService';
import { Writer } from '../../writer/Writer';
import { InventoryInput } from './InventoryInput';
import { ServiceError } from '../base/ServiceError';
import { Operator } from '../base/filters/Operator';
import { AppDataSource } from '../../platform/DataSource';

@Service()
export class InventoryService extends DomainEntityService<Inventory> {
  @Inject()
  protected configurationService: ConfigurationService;

  @Inject()
  protected customerService: CustomerService;

  @Inject()
  protected partnerService: PartnerService;

  @Inject()
  protected dynamicAttrsService: DynamicAttrsService;

  @Inject()
  protected dataFileService: DataFileService;

  @Inject()
  protected submissionPeriodService: SubmissionPeriodService;

  @Inject()
  protected inventoryQuantityService: InventoryQuantityService;

  @Inject()
  protected inventoryPriceService: InventoryPriceService;

  @Inject('Writer')
  protected writer: Writer;

  constructor() {
    super(Inventory);
  }

  getServiceName(): string {
    return 'Inventory';
  }

  async findNeedCorrectionInventory(
    customerId: string,
    partnerId: string,
    options: FindOptions = new FindOptions()
  ): Promise<Inventory[]> {
    const customer = await this.customerService.findOneById(customerId);
    const partner = await this.partnerService.findOneById(partnerId);
    const { offset, limit, filters = {}, sort } = options;

    if (!customer || (!partner && !PartnerService.isAll(partnerId))) {
      return Promise.resolve([]);
    }
    const config = await this.configurationService.getConfiguration(customerId);
    const queueName = config.get('needCorrectionInventoryQueueName', 'resign');
    const maxAge = config.get('nmiMaxAgeInDays', '30');

    const query = this.repository
      .createQueryBuilder('inv')
      .leftJoinAndSelect(
        'inv.dynamicAttrs',
        'da',
        '"da"."ATTRIBUTE_TYPE" = \'IL\' and "da"."CUSTOMER_SID" = "inv"."CUSTOMER_SID"'
      )
      .innerJoinAndSelect(
        'inv.dataFile',
        'df',
        '"df"."CUSTOMER_SID" = "inv"."CUSTOMER_SID"'
      )
      .leftJoinAndSelect(
        'inv.submissionPeriod',
        'sp',
        '"sp"."CUSTOMER_SID" = "inv"."CUSTOMER_SID"'
      )      
      .leftJoinAndSelect(
        'sp.submissionSchedule',
        'ss',
        '"sp"."CUSTOMER_SID" = "ss"."CUSTOMER_SID"'
      )
      .leftJoinAndSelect('ss.dataType', 'dt')
      .leftJoinAndSelect(
        'sp.submissionPeriodLineItemView',
        'spli',
        '"sp"."CUSTOMER_SID" = "spli"."CUSTOMER_SID"'
      )
      .leftJoinAndSelect(
        'sp.dataFileSummaryInfo',
        'dfsi',
        '"sp"."CUSTOMER_SID" = "dfsi"."CUSTOMER_SID"'
      )
      .leftJoinAndMapOne(
        'inv.onHandQuantity',
        'inv.inventoryQuantities',
        'onHandInvQuantity',
        '"onHandInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'ON HAND\')'
      )
      .leftJoinAndMapOne(
        'inv.onOrderQuantity',
        'inv.inventoryQuantities',
        'onOrderInvQuantity',
        '"onOrderInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'ON ORDER\')'
      )
      .leftJoinAndMapOne(
        'inv.committedQuantity',
        'inv.inventoryQuantities',
        'committedInvQuantity',
        '"committedInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'COMMITTED\')'
      )
      .leftJoinAndMapOne(
        'inv.floatQuantity',
        'inv.inventoryQuantities',
        'floatInvQuantity',
        '"floatInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'FLOAT\')'
      )
      .leftJoinAndMapOne(
        'inv.backorderedQuantity',
        'inv.inventoryQuantities',
        'backorderedInvQuantity',
        '"backorderedInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'BACKORDERED\')'
      )
      .leftJoinAndMapOne(
        'inv.returnedQuantity',
        'inv.inventoryQuantities',
        'returnedInvQuantity',
        '"returnedInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'RETURNED\')'
      )
      .leftJoinAndMapOne(
        'inv.inTransitQuantity',
        'inv.inventoryQuantities',
        'inTransitInvQuantity',
        '"inTransitInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'TRANSIT\')'
      )
      .leftJoinAndMapOne(
        'inv.unitPrice',
        'inv.inventoryPrices',
        'invPrice',
        '"invPrice"."PRICE_TYPE_SID" = ( SELECT SID FROM PRICE_TYPE WHERE ' +
          'NAME = \'REPORTED_PRICE\') AND "invPrice"."DELETED" = 0'
      )
      .innerJoin(
        'PEH_INV_QUEUE',
        'piq',
        '"piq"."CLIENT_SKU" = "inv"."CLIENT_SKU" and "piq"."INV_LINE_ITEM_SID" = "inv"."SID" ' +
          'and "piq"."CUSTOMER_SID" = "inv"."CUSTOMER_SID"'
      )
      .offset(offset)
      .limit(limit);    

    // add filters for quantity filters
    let quantityFiltersMap = new Map();
    quantityFiltersMap.set('onOrderQuantity', 'onOrderInvQuantity');
    quantityFiltersMap.set('onHandQuantity', 'onHandInvQuantity');
    quantityFiltersMap.set('committedQuantity', 'committedInvQuantity');
    quantityFiltersMap.set('floatQuantity', 'floatInvQuantity');
    quantityFiltersMap.set('backorderedQuantity', 'backorderedInvQuantity');
    quantityFiltersMap.set('returnedQuantity', 'returnedInvQuantity');
    quantityFiltersMap.set('inTransitQuantity', 'inTransitInvQuantity');

    for (let [key, value] of quantityFiltersMap) {
      const quantityFilters = filters[key];
      delete filters[key];
      if (quantityFilters) {
        const quantityWhere =
          this.inventoryQuantityService.buildWhereExpression(
            quantityFilters,
            value
          );
        query.andWhere(quantityWhere);
      }
    }    

    // add unit price condition
    const unitPriceFilters = filters['unitPrice'];
    delete filters['unitPrice'];
    if (unitPriceFilters) {
      const unitPriceWhere = this.inventoryPriceService.buildWhereExpression(
        unitPriceFilters,
        'invPrice'
      );
      query.andWhere(unitPriceWhere);
    }    

    this.buildWhere(filters, query);
    query.andWhere('"inv"."CUSTOMER_SID" = ' + customer.sid)
    .andWhere('"inv"."INVENTORY_DATE" >= sysdate - ' + maxAge)
    .andWhere('"piq"."QUEUE_NAME" = \'' + queueName + "'")
    .andWhere( { 'deleted' : Equal(0) } );

    if (!PartnerService.isAll(partnerId)) {
      query.andWhere('"inv"."REPORTING_PARTNER_SID" = ' + partner.sid);
    }
    
    // add order by
    this.addOrderBys(query, sort);

    return query.getMany();
  }

  async updateInventory(
    customerId: string,
    partnerId: string,
    data: InventoryInput[]
  ): Promise<ServiceError[]> {
    let inventoryToCreate: Inventory[] = [];
    let sids: number[] = data.map((input: InventoryInput) => {
      return input.sid;
    });
    let errors: ServiceError[] = [];

    // Check if partner has access to ili
    let options: FindOptions = {
      offset: 0,
      limit: 1000,
      filters: {
        sid: {
          operator: Operator.IN,
          values: sids
        }
      }
    };
    let inventory: Inventory[] = await this.findNeedCorrectionInventory(
      customerId,
      partnerId,
      options
    );

    let sidsToUpdate: number[] = [];
    errors = sids.map((sid) => {
      if (inventory) {
        let s: Inventory = inventory.find((inv: Inventory) => {
          return inv.sid.toString() === sid.toString();
        });
        if (s) {
          sidsToUpdate.push(sid);
          return null;
        }
      }
      return new ServiceError(
        'INVENTORY_NOT_FOUND',
        `Inventory line sid : ${sid} not found`
      );
    });

    if (inventory && inventory.length > 0) {
      let invLineItems: Inventory[] = await this.repository
        .createQueryBuilder('inv')
        // load partner and gs number
        .innerJoinAndSelect('inv.reportingPartner', 'rp')
        .leftJoinAndSelect('rp.gsNumbers', 'gs')
        // load dynamic attrs
        .leftJoinAndSelect('inv.dynamicAttrs', 'da')
        .leftJoinAndMapOne(
          'inv.onHandQuantity',
          'inv.inventoryQuantities',
          'onHandInvQuantity',
          '"onHandInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'ON HAND\')'
        )
        .leftJoinAndMapOne(
          'inv.onOrderQuantity',
          'inv.inventoryQuantities',
          'onOrderInvQuantity',
          '"onOrderInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'ON ORDER\')'
        )
        .leftJoinAndMapOne(
          'inv.committedQuantity',
          'inv.inventoryQuantities',
          'committedInvQuantity',
          '"committedInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'COMMITTED\')'
        )
        .leftJoinAndMapOne(
          'inv.floatQuantity',
          'inv.inventoryQuantities',
          'floatInvQuantity',
          '"floatInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'FLOAT\')'
        )
        .leftJoinAndMapOne(
          'inv.backorderedQuantity',
          'inv.inventoryQuantities',
          'backorderedInvQuantity',
          '"backorderedInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'BACKORDERED\')'
        )
        .leftJoinAndMapOne(
          'inv.returnedQuantity',
          'inv.inventoryQuantities',
          'returnedInvQuantity',
          '"returnedInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'RETURNED\')'
        )
        .leftJoinAndMapOne(
          'inv.inTransitQuantity',
          'inv.inventoryQuantities',
          'inTransitInvQuantity',
          '"inTransitInvQuantity"."QUANTITY_TYPE_SID" = ( SELECT SID FROM QUANTITY_TYPE WHERE QUANTITY_TYPE = \'TRANSIT\')'
        )
        .leftJoinAndMapOne(
          'inv.unitPrice',
          'inv.inventoryPrices',
          'invPrice',
          '"invPrice"."PRICE_TYPE_SID" = ( SELECT SID FROM PRICE_TYPE WHERE NAME = \'REPORTED_PRICE\') AND "invPrice"."DELETED" = 0'
        )
        .where({ sid: In(sidsToUpdate) })
        .andWhere('"gs"."CUSTOMER_SID" = :customerSid', {
          customerSid: inventory[0].customerSid
        })
        .getMany();

      await Promise.all(
        invLineItems.map(async (invLineItem) => {
          // load serial numbers

          let input: InventoryInput = data.find((inv: InventoryInput) => {
            return inv.sid.toString() === invLineItem.sid.toString();
          });

          invLineItem = Object.assign({}, invLineItem, input);

          // add inv line to list to write to S3.
          inventoryToCreate.push(invLineItem);
        })
      );

      console.log(`Inventory to write to S3 : ${inventoryToCreate.length}`);
      // Write to S3
      if (inventoryToCreate.length > 0) {
        await this.writer.write(
          customerId,
          partnerId,
          this.getServiceName(),
          inventoryToCreate
        );
      }

      // It is safe to delete from PEH after writing to S3, just in case if delete fails,
      // the inv will still be deleted from PEH the json file from S3 is loaded into nucleus.
      // If we delete first and for some reason the writing to S3 fails, there is no way to roll back the db update.
      await Promise.all(
        inventoryToCreate.map(async (invLineItem) => {
          try {
            // delete inventory line from PEH
            await AppDataSource.query(
              'delete from peh_inv_queue where inv_line_item_sid = :sid',
              [invLineItem.sid]
            );
            console.log(`Deleted line item : ${invLineItem.sid} from PEH`);
          } catch (e) {
            console.log(
              `Error while deleting from PEH for inv line : ${JSON.stringify(
                invLineItem
              )} for Customer : ${customerId}`
            );
            console.error(e);
            // eat the error as if delete fails, the only con is User will still be able to see the inv line
            // until the file on S3 is loaded into nucleus
          }
        })
      );
    }

    return errors;
  }
}
import { Inject, Service } from 'typedi';
import { DomainEntityService } from '../base/DomainEntityService';
import { DataFileSummaryInfo } from './DataFileSummaryInfo';
import { CustomerService } from '../customer/CustomerService';
import { SubmissionPeriodService } from '../submission/SubmissionPeriodService';

@Service()
export class DataFileSummaryInfoService extends DomainEntityService<DataFileSummaryInfo> {
  @Inject()
  protected customerService: CustomerService;

  @Inject()
  protected submissionPeriodService: SubmissionPeriodService;

  constructor() {
    super(DataFileSummaryInfo);
  }

  getServiceName() {
    return 'DataFileSummaryInfo';
  }

  async createDataFileSummaryInfo(
    custId: string,
    submissionPeriodSid: number,
    dataFileSid: number,
    numberOfPOSLines: number,
    numberOfInventoryLines: number
  ) {
    const cust = await this.customerService.findOneById(custId);

    await this.create({
      customerSid: cust.sid,
      submissionPeriodSid: submissionPeriodSid,
      dataFileSid: dataFileSid,
      numberOfPOSLines: numberOfPOSLines,
      numberOfInventoryLines: numberOfInventoryLines,
    });
}

}
import { Entity, Column, ManyToOne, JoinColumn} from 'typeorm';
import { CustomerDomainEntity } from '../base/CustomerDomainEntity';
import { returnsSubmissionPeriod } from '../submission/SubmissionPeriod';
import { SubmissionPeriod } from '../submission/SubmissionPeriod';

export const returnsDataFileSummaryInfo = () => DataFileSummaryInfo;
export const returnsSubmissionPeriods = (submissionPeriod) => submissionPeriod.filesData;

@Entity({ name: 'DATA_FILE_SUMMARY_INFO' })
export class DataFileSummaryInfo extends CustomerDomainEntity {

    @ManyToOne(() => SubmissionPeriod)
    @JoinColumn([
        { name: 'SUBMISSION_PERIOD_SID', referencedColumnName: 'sid' },
        { name: 'CUSTOMER_SID', referencedColumnName: 'customerSid' }
    ])
    submissionPeriod: SubmissionPeriod;

    @Column({name:'DATA_FILE_SID'})
    dataFileSid: number;

    @Column({name:'NUM_SLIS'})
    numberOfPOSLines: number;

    @Column({name:'NUM_ILIS'})
    numberOfInventoryLines: number;
    
    // Specify that submissionPeriodSid can be null
    @Column({ name: 'SUBMISSION_PERIOD_SID', nullable: true })
    submissionPeriodSid: number;
}

import { Entity, Column, ManyToOne, JoinColumn} from 'typeorm';
import { CustomerDomainEntity } from '../base/CustomerDomainEntity';
import { returnsSubmissionPeriod } from '../submission/SubmissionPeriod';
import { SubmissionPeriod } from '../submission/SubmissionPeriod';

export const returnsDataFileSummaryInfo = () => DataFileSummaryInfo;
export const returnsSubmissionPeriods = (submissionPeriod) => submissionPeriod.filesData;

@Entity({ name: 'DATA_FILE_SUMMARY_INFO' })
export class DataFileSummaryInfo extends CustomerDomainEntity {

    @ManyToOne(() => SubmissionPeriod)
    @JoinColumn([
        { name: 'SUBMISSION_PERIOD_SID', referencedColumnName: 'sid' },
        { name: 'CUSTOMER_SID', referencedColumnName: 'customerSid' }
    ])
    submissionPeriod: SubmissionPeriod;

    @Column({name:'DATA_FILE_SID'})
    dataFileSid: number;

    @Column({name:'NUM_SLIS'})
    numberOfPOSLines: number;

    @Column({name:'NUM_ILIS'})
    numberOfInventoryLines: number;
    
    // Specify that submissionPeriodSid can be null
    @Column({ name: 'SUBMISSION_PERIOD_SID', nullable: true })
    submissionPeriodSid: number;
}

import { Entity, Column, ManyToOne, JoinColumn} from 'typeorm';
import { CustomerDomainEntity } from '../base/CustomerDomainEntity';
import { returnsSubmissionPeriod } from '../submission/SubmissionPeriod';

export const returnsDataFileSummaryInfo = () => DataFileSummaryInfo;
export const returnsSubmissionPeriods = (submissionPeriod) => submissionPeriod.filesData;

@Entity({ name: 'DATA_FILE_SUMMARY_INFO' })
export class DataFileSummaryInfo extends CustomerDomainEntity {

    @ManyToOne(returnsSubmissionPeriod, returnsSubmissionPeriods)
    @JoinColumn([
        { name: 'SUBMISSION_PERIOD_SID', referencedColumnName: 'sid' },
        { name: 'CUSTOMER_SID', referencedColumnName: 'customerSid' }
    ])
    submissionPeriodSid: number;

    @Column({name:'DATA_FILE_SID'})
    dataFileSid: number;

    @Column({name:'NUM_SLIS'})
    numberOfPOSLines: number;

    @Column({name:'NUM_ILIS'})
    numberOfInventoryLines: number;
    
}

import { Entity, Column, JoinColumn, OneToOne, VirtualColumn, OneToMany } from 'typeorm';
import { CustomerDomainEntity } from '../base/CustomerDomainEntity';
import {
  returnsSubmissionPeriodLineItemView,
  SubmissionPeriodLineItemView
} from './SubmissionPeriodLineItemView';
import {
  reportedFlagSql,
  statusSql,
  fileIdsSql,
  filesCountSql,
  filesDataSql
} from './SubmissionPeriodSql';
import {
  returnsSubmissionSchedule,
  SubmissionSchedule
} from './SubmissionSchedule';
import { ServiceUser, returnsServiceUser } from '../user/ServiceUser';
import { DataFileSummaryInfo, returnsDataFileSummaryInfo } from '../datafile/DataFileSummaryInfo';

export const returnsSubmissionPeriod = () => SubmissionPeriod;
export const dataFileSummaryInfoInverseSide = (dataFileSummaryInfo) =>
  dataFileSummaryInfo.submissionPeriod;

@Entity({ name: 'SUBMISSION_PERIOD' })
export class SubmissionPeriod extends CustomerDomainEntity {
  @Column({ name: 'EXPECTED_DATE' })
  expectedDate: Date;

  @Column({ name: 'PERIOD_START_DATE' })
  periodStartDate: Date;

  @Column({ name: 'PERIOD_END_DATE' })
  periodEndDate: Date;

  @Column({ name: 'SUBMISSION_SCHEDULE_SID', select: false })
  submissionScheduleSid: number;

  @Column({ name: 'ON_TIME_OVERRIDE' })
  onTimeOverride: boolean;

  @Column({ name: 'NO_DATA' })
  noData: boolean;

  @Column({ name: 'NO_DATA_REASON' })
  noDataReason: string;

  @Column({ name: 'NO_DATA_CREATE_DATE' })
  noDataCreateDate: Date;

  @Column({ name: 'NO_DATA_SERVICE_USER_SID', select: false })
  noDataServiceUserSid: number;

  @OneToOne(returnsServiceUser)
  @JoinColumn({ name: 'NO_DATA_SERVICE_USER_SID' })
  noDataServiceUser: Promise<ServiceUser>;

  @Column({ name: 'TRACKING_LEVEL' })
  trackingLevel: string;

  @Column({ name: 'EXPECTED_DAY' })
  expectedDay: number;

  @Column({ name: 'WORKING_DAYS' })
  workingDays: string;

  @Column({ name: 'IS_IN_PERIOD_REPORTER' })
  isInPeriodReporter: number;

  @Column({ name: 'DELETED' })
  deleted: boolean;

  @OneToOne(returnsSubmissionSchedule)
  @JoinColumn({ name: 'SUBMISSION_SCHEDULE_SID' })
  submissionSchedule?: Promise<SubmissionSchedule>;

  @VirtualColumn({ query: statusSql })
  status?: string;

  @VirtualColumn({ query: reportedFlagSql })
  reportedFlag: boolean;

  @VirtualColumn( {query : fileIdsSql} )
  fileIds?: string;

  firstFileId?: string;

  firstFileName?: string;

  firstFileCreateDate?: Date;

  @VirtualColumn( {query : filesCountSql} )
  numberOfFiles?: number;

  @OneToMany(returnsDataFileSummaryInfo, dataFileSummaryInfoInverseSide)
  @JoinColumn({ name: 'SID', referencedColumnName: 'submissionPeriodSid' })
  filesData?: Promise<DataFileSummaryInfo>;

  @OneToOne(returnsSubmissionPeriodLineItemView)
  @JoinColumn({ name: 'SID', referencedColumnName: 'submissionPeriodSid' })
  submissionPeriodLineItemView?: Promise<SubmissionPeriodLineItemView>;

}
export const SubmissionDef = `
  type Query {
    submissionPeriods(
      offset: Float, 
      limit: Float,
      filters: SubmissionPeriodFilters,
      sort: SubmissionPeriodSort
    ): [SubmissionPeriod]
    submissionSchedules(
      offset: Float, 
      limit: Float,
      filters: SubmissionScheduleFilters, 
      sort: SubmissionScheduleSort
    ): [SubmissionSchedule]
    submissionScheduleNotifications(
      submissionScheduleSid: ID,
      offset: Float,
      limit: Float,
      filters: SubmissionScheduleNotificationFilters,
      sort: SubmissionScheduleNotificationSort
    ): [SubmissionScheduleNotification]
  }

  type Mutation {
    markNoData(data: [NoDataInput]): [MutationResponse] @auth(object: SubmissionPeriod)
  }

  type SubmissionPeriod {
    sid: ID
    createDate: Date
    updateDate: Date
    customerSid: ID
    expectedDate: Date
    periodStartDate: Date
    periodEndDate: Date
    noData: Boolean
    noDataReason: String
    noDataCreateDate: Date
    onTimeOverride: Boolean
    expectedDay: String
    workingDays: String
    isInPeriodReporter: Float
    trackingLevel: String
    submissionSchedule: SubmissionSchedule
    status: String
    reportedFlag: Boolean
    numberOfFiles: Float
    filesData: DataFileSummaryInfo
    submissionPeriodLineItemView: SubmissionPeriodLineItemView
    noDataServiceUser: ServiceUser
  }

  type SubmissionPeriodLineItemView {
    salesLineItemCount: Float
    invLineItemCount: Float
    earliestFileSubmissionDate: Date
  }

  
  type DataFileSummaryInfo{
    numberOfPOSLines: Float
    numberOfInventoryLines: Float
  }
  
  type SubmissionSchedule {
    sid: ID
    createDate: Date
    updateDate: Date
    customerSid: ID
    dataType: DataType    
    reportingPartner: Partner
    periodRule: String
    name: String
    startDate: Date
    endDate: Date
    expectedDay: String
    workingDays: String
    isInPeriodReporter: Boolean
    weekOfMonth: Float
    monthOfQuarter: Float
  }

  type DataType {
    sid: ID
    createDate: Date
    updateDate: Date
    type: String
  }

  type SubmissionScheduleNotification {
    sid: ID
    createDate: Date
    updateDate: Date
    customerSid: ID
    submissionScheduleSid: ID
    notificationType: NotificationType
    serviceUser: ServiceUser
  }

  enum NotificationType {
    PARSE_SUCCESS
    LATE
    PARSE_FAIL
    EXPECTED
  }

  input SubmissionPeriodFilters {
    sid: IDFilter
    createDate: DateFilter
    updateDate: DateFilter
    customerSid: IDFilter
    expectedDate: DateFilter
    periodStartDate: DateFilter
    periodEndDate: DateFilter
    submissionSchedule: SubmissionScheduleFilters
    status: StringFilter
    reportedFlag: BooleanFilter
    submissionPeriodLineItemView: SubmissionPeriodLineItemViewFilter
    numberOfFiles: NumberFilter
  }
  
  input SubmissionPeriodLineItemViewFilter {
    salesLineItemCount: NumberFilter
    invLineItemCount: NumberFilter
    earliestFileSubmissionDate: DateFilter
  }

  input SubmissionScheduleFilters {
    sid: IDFilter
    createDate: DateFilter
    updateDate: DateFilter
    customerSid: IDFilter
    reportingPartner: PartnerFilter
    name: StringFilter
    dataType: DataTypeFilter
    periodRule: StringFilter
    expectedDay: StringFilter
    workingDays: StringFilter
    startDate: DateFilter
    endDate: DateFilter
    isInPeriodReporter: BooleanFilter
    weekOfMonth: NumberFilter
    monthOfQuarter: NumberFilter
  }

  input DataTypeFilter {
    sid: IDFilter
    createDate: DateFilter
    updateDate: DateFilter
    type: StringFilter
  }

  input SubmissionScheduleNotificationFilters {
    sid: IDFilter
    createDate: DateFilter
    updateDate: DateFilter
    customerSid: IDFilter
    submissionScheduleSid: IDFilter
    notificationType: StringFilter
    serviceUser: ServiceUserFilters
  }

  input SubmissionPeriodSort {
    sid: SortOption
    createDate: SortOption
    updateDate: SortOption
    expectedDate: SortOption
    periodStartDate: SortOption
    periodEndDate: SortOption
    submissionSchedule: SubmissionScheduleSort
    status: SortOption
    reportedFlag: SortOption
    submissionPeriodLineItemView: SubmissionPeriodLineItemViewSort
    numberOfFiles: SortOption
  }
  
  input SubmissionPeriodLineItemViewSort {
    salesLineItemCount: SortOption
    invLineItemCount: SortOption
    earliestFileSubmissionDate: SortOption
  }

  input SubmissionScheduleSort {
    sid: SortOption
    createDate: SortOption
    updateDate: SortOption
    customerSid: SortOption
    dataType: DataTypeSort
    reportingPartner: PartnerSort
    periodRule: SortOption
    name: SortOption
    startDate: SortOption
    endDate: SortOption
    expectedDay: SortOption
    workingDays: SortOption
    isInPeriodReporter: SortOption
    weekOfMonth: SortOption
    monthOfQuarter: SortOption
  }

  input DataTypeSort {
    sid: SortOption
    createDate: SortOption
    updateDate: SortOption
    type: SortOption
  }

  input SubmissionScheduleNotificationSort {
    sid: SortOption
    createDate: SortOption
    updateDate: SortOption
    notificationType: SortOption
    serviceUser: ServiceUserSort
  }

  input NoDataInput {
    sid: ID!
    noDataReason: String
  }
`;
ALTER TABLE your_table_name
RENAME COLUMN old_column_name TO new_column_name;
ALTER TABLE your_table_name
ADD COLUMN new_column_name INT;
export const deletedLinesSql = (alias: string) => {
  return `
  (SELECT sum(CNT) AS "DELETED_COUNT"
  FROM (
      SELECT 
        COUNT("sli"."SID") "CNT" 
      FROM 
        data_file "df1" 
          LEFT JOIN sales_line_item "sli"
              ON "sli"."DATA_FILE_SID" = "df1"."SID" 
                  AND "sli"."CUSTOMER_SID" = "df1"."CUSTOMER_SID" 
                  AND "sli"."DELETED" = 1 
                  AND "sli"."RESUBMITTED" = 0 
      WHERE "df1"."SID" = ${alias}."SID"
          AND "df1"."CUSTOMER_SID" = ${alias}."CUSTOMER_SID"
      GROUP BY "df1"."SID" 
      UNION ALL 
      SELECT 
        COUNT("ili"."SID") "CNT" 
      FROM 
        data_file "df1" 
          LEFT JOIN inv_line_item "ili"
              ON "ili"."DATA_FILE_SID" = "df1"."SID" 
                  AND "ili"."CUSTOMER_SID" = "df1"."CUSTOMER_SID" 
                  AND "ili"."DELETED" = 1 
                  AND "ili"."RESUBMITTED" = 0 
      WHERE 
        "df1"."SID" = ${alias}."SID"
        and "df1"."CUSTOMER_SID" = ${alias}."CUSTOMER_SID"
      group by 
        "df1"."SID"
    ))
`;
};
select data_file_sid,customer_sid from sales_line_item where deleted=1 and data_file_sid != 8423737 and data_file_sid!=8424107;

SELECT sum(cnt) AS DELETED_COUNT
  FROM (
      SELECT 
        COUNT(sli.sid) cnt 
      FROM 
        data_file df1 
          LEFT JOIN sales_line_item sli
              ON sli.data_file_sid = df1.sid 
                  AND sli.customer_sid = df1.customer_sid 
                  AND sli.DELETED = 1 
                  AND sli.RESUBMITTED = 0 
      WHERE df1.sid = :sid
          AND df1.customer_sid = :cs
      GROUP BY df1.sid 
      UNION ALL 
      SELECT 
        COUNT(ili.sid) cnt 
      FROM 
        data_file df1 
          LEFT JOIN inv_line_item ili
              ON ili.data_file_sid = df1.sid 
                  AND ili.customer_sid = df1.customer_sid 
                  AND ili.DELETED = 1 
                  AND ili.RESUBMITTED = 0 
      WHERE 
        df1.sid = :sid
        and df1.customer_sid = :cs
      group by 
        df1.sid)
registry=http://registry.npmjs.org/
//npm.pkg.github.com/:_authToken=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

{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Launch via NPM-thanuj",
            "type": "node",
            "request": "launch",
            "cwd": "${workspaceRoot}",
            "runtimeExecutable": "npm",
            "runtimeArgs": [
                "run",  "sam"
            ],
            "port": 5858,
            "env": {
                "NODE_PATH": "${cwd}",
                "DBHOST": "vi-cdm-tdbp03.aws.modeln.com",
                "DBSERVICE": "cdmsbx",
                "DBUSER": "nucleus",
                "DBPASS": "notFunnyYoke",
                "AWS_PROFILE":"qa",
                "AUTHORIZER": "DEV",
                "CACHE_STORE": "memory"
            }
        }
  
    ]
  }
import { Entity, Column, JoinColumn, OneToOne, VirtualColumn } from 'typeorm';
import { CustomerDomainEntity } from '../base/CustomerDomainEntity';
import {
  returnsSubmissionPeriodLineItemView,
  SubmissionPeriodLineItemView
} from './SubmissionPeriodLineItemView';
import {
  reportedFlagSql,
  statusSql,
  filesCountSql
} from './SubmissionPeriodSql';
import {
  returnsSubmissionSchedule,
  SubmissionSchedule
} from './SubmissionSchedule';
import { ServiceUser, returnsServiceUser } from '../user/ServiceUser';

export const returnsSubmissionPeriod = () => SubmissionPeriod;

@Entity({ name: 'SUBMISSION_PERIOD' })
export class SubmissionPeriod extends CustomerDomainEntity {
  @Column({ name: 'EXPECTED_DATE' })
  expectedDate: Date;

  @Column({ name: 'PERIOD_START_DATE' })
  periodStartDate: Date;

  @Column({ name: 'PERIOD_END_DATE' })
  periodEndDate: Date;

  @Column({ name: 'SUBMISSION_SCHEDULE_SID', select: false })
  submissionScheduleSid: number;

  @Column({ name: 'ON_TIME_OVERRIDE' })
  onTimeOverride: boolean;

  @Column({ name: 'NO_DATA' })
  noData: boolean;

  @Column({ name: 'NO_DATA_REASON' })
  noDataReason: string;

  @Column({ name: 'NO_DATA_CREATE_DATE' })
  noDataCreateDate: Date;

  @Column({ name: 'NO_DATA_SERVICE_USER_SID', select: false })
  noDataServiceUserSid: number;

  @OneToOne(returnsServiceUser)
  @JoinColumn({ name: 'NO_DATA_SERVICE_USER_SID' })
  noDataServiceUser: Promise<ServiceUser>;

  @Column({ name: 'TRACKING_LEVEL' })
  trackingLevel: string;

  @Column({ name: 'EXPECTED_DAY' })
  expectedDay: number;

  @Column({ name: 'WORKING_DAYS' })
  workingDays: string;

  @Column({ name: 'IS_IN_PERIOD_REPORTER' })
  isInPeriodReporter: number;

  @Column({ name: 'DELETED' })
  deleted: boolean;

  @OneToOne(returnsSubmissionSchedule)
  @JoinColumn({ name: 'SUBMISSION_SCHEDULE_SID' })
  submissionSchedule?: Promise<SubmissionSchedule>;

  @VirtualColumn({ query: statusSql })
  status?: string;

  @VirtualColumn({ query: reportedFlagSql })
  reportedFlag: boolean;

  @VirtualColumn( {query : filesCountSql} )
  numberOfFiles: number;

  @OneToOne(returnsSubmissionPeriodLineItemView)
  @JoinColumn({ name: 'SID', referencedColumnName: 'submissionPeriodSid' })
  submissionPeriodLineItemView?: Promise<SubmissionPeriodLineItemView>;

}
export const statusSql = (alias: string) => {
     return `(select
             CASE WHEN ( ${alias}."ON_TIME_OVERRIDE" = 1) 
                  THEN 'On-time'
                  WHEN ( "spli1"."EARLIEST_FILE_SUBMISSION_DATE" < ${alias}."EXPECTED_DATE" )
                  THEN 'On-time'
                  WHEN ( ( ${alias}."NO_DATA" = 1 ) 
                         AND ( ${alias}."NO_DATA_CREATE_DATE" < ${alias}."EXPECTED_DATE"))
                  THEN 'On-time'
                  WHEN ( ${alias}."EXPECTED_DATE" > SYSTIMESTAMP)
                  THEN 'Pending'
                  ELSE 'Late'
             END
             from SUBMISSION_PERIOD "sp1"
             left join SUBMISSION_PERIOD_LINE_ITEM_V "spli1" on 
                                                     "spli1"."SUBMISSION_PERIOD_SID" = "sp1"."SID"
                                                     AND "spli1"."CUSTOMER_SID" = "sp1"."CUSTOMER_SID"
             where "sp1"."SID" = ${alias}."SID"
             AND "sp1"."CUSTOMER_SID" = ${alias}."CUSTOMER_SID")`;
};

export const reportedFlagSql = (alias: string) => {
     return `(select
             CASE WHEN MAX(${alias}."ON_TIME_OVERRIDE") = 1
                  THEN 1
                  WHEN MAX(${alias}."NO_DATA") = 1
                  THEN 1
                  WHEN COUNT("df"."ID") > 0
                  THEN 1
                  ELSE 0
             END
             from SUBMISSION_SCHEDULE "ss1"
             left join DATA_FILE_SUMMARY_INFO "dfsi" on 
                                              "dfsi"."SUBMISSION_PERIOD_SID" = ${alias}."SID"
                                              AND "dfsi"."CUSTOMER_SID" = ${alias}."CUSTOMER_SID"
             left join DATA_TYPE "dt1" on "ss1"."DATA_TYPE_SID" = "dt1"."SID"
             left join DATA_FILE "df" on "dfsi"."CUSTOMER_SID" = "df"."CUSTOMER_SID"
                                 AND "dfsi"."DATA_FILE_SID" = "df"."SID"
                                 AND "df"."DATA_TYPE" = "dt1"."TYPE"  
             where "ss1"."SID" = ${alias}."SUBMISSION_SCHEDULE_SID"
             AND "ss1"."CUSTOMER_SID" = ${alias}."CUSTOMER_SID")`
};

export const fileIdsSql = (alias: string) => { 
    return `(select
             listagg("df"."ID",',') within group (ORDER BY "df"."CREATE_DATE")
             from SUBMISSION_SCHEDULE "ss1"
             left join DATA_FILE_SUMMARY_INFO "dfsi" on 
                                              "dfsi"."SUBMISSION_PERIOD_SID" = ${alias}."SID"
                                              AND "dfsi"."CUSTOMER_SID" = ${alias}."CUSTOMER_SID"
             left join DATA_TYPE "dt1" on "ss1"."DATA_TYPE_SID" = "dt1"."SID"
             left join DATA_FILE "df" on "dfsi"."CUSTOMER_SID" = "df"."CUSTOMER_SID"
                                 AND "dfsi"."DATA_FILE_SID" = "df"."SID"
                                 AND "df"."DELETED" = 0
                                 AND "df"."DATA_TYPE" = "dt1"."TYPE"  
             where "ss1"."SID" = ${alias}."SUBMISSION_SCHEDULE_SID"
             AND "ss1"."CUSTOMER_SID" = ${alias}."CUSTOMER_SID")`
};

export const filesCountSql = (alias: string) => {
     return `(select
          count(df.id) as number_of_files
          from SUBMISSION_SCHEDULE ss1
          left join DATA_FILE_SUMMARY_INFO dfsi on 
                                           dfsi.SUBMISSION_PERIOD_SID =  ${alias}.SID
                                           AND dfsi.CUSTOMER_SID = ${alias}.CUSTOMER_SID
          left join DATA_TYPE dt1 on ss1.DATA_TYPE_SID = dt1.SID
          left join DATA_FILE df on dfsi.CUSTOMER_SID = df.CUSTOMER_SID
                              AND dfsi.DATA_FILE_SID = df.SID
                              AND df.DELETED = 0
                              AND df.DATA_TYPE = dt1.TYPE
          where ss1.SID = ${alias}.SUBMISSION_SCHEDULE_SID
          AND ss1.CUSTOMER_SID= ${alias}.CUSTOMER_SID)`
}

export const filesDataSql = (alias:string) => {
     return `(select
          df.id,df.file_name,df.record_count,dfsi.num_slis,dfsi.num_ilis
          from SUBMISSION_SCHEDULE ss1
          left join DATA_FILE_SUMMARY_INFO dfsi on 
                                           dfsi.SUBMISSION_PERIOD_SID = ${alias}.SID
                                           AND dfsi.CUSTOMER_SID = ${alias}.CUSTOMER_SID
          left join DATA_TYPE dt1 on ss1.DATA_TYPE_SID = dt1.SID
          left join DATA_FILE df on dfsi.CUSTOMER_SID = df.CUSTOMER_SID
                              AND dfsi.DATA_FILE_SID = df.SID
                              AND df.DELETED = 0
                              AND df.DATA_TYPE = dt1.TYPE
          where ss1.SID = ${alias}.SUBMISSION_SCHEDULE_SID
          AND ss1.CUSTOMER_SID= ${alias}.CUSTOMER_SID)`
}
export const SubmissionDef = `
  type Query {
    submissionPeriods(
      offset: Float, 
      limit: Float,
      filters: SubmissionPeriodFilters,
      sort: SubmissionPeriodSort
    ): [SubmissionPeriod]
    submissionSchedules(
      offset: Float, 
      limit: Float,
      filters: SubmissionScheduleFilters, 
      sort: SubmissionScheduleSort
    ): [SubmissionSchedule]
    submissionScheduleNotifications(
      submissionScheduleSid: ID,
      offset: Float,
      limit: Float,
      filters: SubmissionScheduleNotificationFilters,
      sort: SubmissionScheduleNotificationSort
    ): [SubmissionScheduleNotification]
  }

  type Mutation {
    markNoData(data: [NoDataInput]): [MutationResponse] @auth(object: SubmissionPeriod)
  }

  type SubmissionPeriod {
    sid: ID
    createDate: Date
    updateDate: Date
    customerSid: ID
    expectedDate: Date
    periodStartDate: Date
    periodEndDate: Date
    noData: Boolean
    noDataReason: String
    noDataCreateDate: Date
    onTimeOverride: Boolean
    expectedDay: String
    workingDays: String
    isInPeriodReporter: Float
    trackingLevel: String
    submissionSchedule: SubmissionSchedule
    status: String
    reportedFlag: Boolean
    numberOfFiles: number
    submissionPeriodLineItemView: SubmissionPeriodLineItemView
  }

  type SubmissionPeriodLineItemView {
    salesLineItemCount: Float
    invLineItemCount: Float
    earliestFileSubmissionDate: Date
  }
  
  type SubmissionSchedule {
    sid: ID
    createDate: Date
    updateDate: Date
    customerSid: ID
    dataType: DataType    
    reportingPartner: Partner
    periodRule: String
    name: String
    startDate: Date
    endDate: Date
    expectedDay: String
    workingDays: String
    isInPeriodReporter: Boolean
    weekOfMonth: Float
    monthOfQuarter: Float
  }

  type DataType {
    sid: ID
    createDate: Date
    updateDate: Date
    type: String
  }

  type SubmissionScheduleNotification {
    sid: ID
    createDate: Date
    updateDate: Date
    customerSid: ID
    submissionScheduleSid: ID
    notificationType: NotificationType
    serviceUser: ServiceUser
  }

  enum NotificationType {
    PARSE_SUCCESS
    LATE
    PARSE_FAIL
    EXPECTED
  }

  input SubmissionPeriodFilters {
    sid: IDFilter
    createDate: DateFilter
    updateDate: DateFilter
    customerSid: IDFilter
    expectedDate: DateFilter
    periodStartDate: DateFilter
    periodEndDate: DateFilter
    submissionSchedule: SubmissionScheduleFilters
    status: StringFilter
    reportedFlag: BooleanFilter
    submissionPeriodLineItemView: SubmissionPeriodLineItemViewFilter
  }
  
  input SubmissionPeriodLineItemViewFilter {
    salesLineItemCount: NumberFilter
    invLineItemCount: NumberFilter
    earliestFileSubmissionDate: DateFilter
  }

  input SubmissionScheduleFilters {
    sid: IDFilter
    createDate: DateFilter
    updateDate: DateFilter
    customerSid: IDFilter
    reportingPartner: PartnerFilter
    name: StringFilter
    dataType: DataTypeFilter
    periodRule: StringFilter
    expectedDay: StringFilter
    workingDays: StringFilter
    startDate: DateFilter
    endDate: DateFilter
    isInPeriodReporter: BooleanFilter
    weekOfMonth: NumberFilter
    monthOfQuarter: NumberFilter
  }

  input DataTypeFilter {
    sid: IDFilter
    createDate: DateFilter
    updateDate: DateFilter
    type: StringFilter
  }

  input SubmissionScheduleNotificationFilters {
    sid: IDFilter
    createDate: DateFilter
    updateDate: DateFilter
    customerSid: IDFilter
    submissionScheduleSid: IDFilter
    notificationType: StringFilter
    serviceUser: ServiceUserFilters
  }

  input SubmissionPeriodSort {
    sid: SortOption
    createDate: SortOption
    updateDate: SortOption
    expectedDate: SortOption
    periodStartDate: SortOption
    periodEndDate: SortOption
    submissionSchedule: SubmissionScheduleSort
    status: SortOption
    reportedFlag: SortOption
    submissionPeriodLineItemView: SubmissionPeriodLineItemViewSort
  }
  
  input SubmissionPeriodLineItemViewSort {
    salesLineItemCount: SortOption
    invLineItemCount: SortOption
    earliestFileSubmissionDate: SortOption
  }

  input SubmissionScheduleSort {
    sid: SortOption
    createDate: SortOption
    updateDate: SortOption
    customerSid: SortOption
    dataType: DataTypeSort
    reportingPartner: PartnerSort
    periodRule: SortOption
    name: SortOption
    startDate: SortOption
    endDate: SortOption
    expectedDay: SortOption
    workingDays: SortOption
    isInPeriodReporter: SortOption
    weekOfMonth: SortOption
    monthOfQuarter: SortOption
  }

  input DataTypeSort {
    sid: SortOption
    createDate: SortOption
    updateDate: SortOption
    type: SortOption
  }

  input SubmissionScheduleNotificationSort {
    sid: SortOption
    createDate: SortOption
    updateDate: SortOption
    notificationType: SortOption
    serviceUser: ServiceUserSort
  }

  input NoDataInput {
    sid: ID!
    noDataReason: String
  }
`;
(select
             df.id,df.file_name,df.record_count,dfsi.num_slis,dfsi.num_ilis
             from SUBMISSION_SCHEDULE ss1
             left join DATA_FILE_SUMMARY_INFO dfsi on 
                                              dfsi.SUBMISSION_PERIOD_SID = :spsid
                                              AND dfsi.CUSTOMER_SID = :spcustomerSid
             left join DATA_TYPE dt1 on ss1.DATA_TYPE_SID = dt1.SID
             left join DATA_FILE df on dfsi.CUSTOMER_SID = df.CUSTOMER_SID
                                 AND dfsi.DATA_FILE_SID = df.SID
                                 AND df.DELETED = 0
                                 AND df.DATA_TYPE = dt1.TYPE
             where ss1.SID = :spsssid
             AND ss1.CUSTOMER_SID= :spcustomersid);--spsid is the input
select SUBMISSION_PERIOD_SID,dfsi.customer_sid,sp.submission_schedule_sid from DATA_FILE_SUMMARY_INFO dfsi right join submission_period sp on dfsi.SUBMISSION_PERIOD_SID = sp.sid order by SUBMISSION_PERIOD_SID asc;