Example #1
0
        public async Task <byte[]> GetAsync(CustomerLedgerSearch option, IProgressNotifier notifier, CancellationToken token = default(CancellationToken))
        {
            var companyTask = companyQueryProcessor.GetAsync(new CompanySearch {
                Id = option.CompanyId,
            }, token);
            var loadTask = customerLedgerProcessor.GetAsync(option, token, notifier);

            await Task.WhenAll(companyTask, loadTask);

            var company = companyTask.Result.First();
            var items   = loadTask.Result.ToList();

            if (!items.Any())
            {
                return(null);
            }

            var report = new CustomerLedgerSectionReport();

            report.SearchOption = option;
            report.SetBasicPageSetting(company.Code, company.Name);
            report.Name = "得意先別消込台帳" + DateTime.Today.ToString("yyyyMMdd");
            report.SetData(items, option.Precision);

            report.Run();

            return(report.Convert());
        }
        /// <summary>消込記号用 消込ヘッダー取得</summary>
        /// <param name="searchOption"></param>
        /// <returns>債権代表者ID, 消込ヘッダーID</returns>
        public async Task <IEnumerable <KeyValuePair <int, long> > > GetKeysAsync(CustomerLedgerSearch searchOption, CancellationToken token, IProgressNotifier notifier)
        {
            var items = await dbHelper.GetItemsAsync <KeyValuePair <int, long> >(CreateSelectKeys(searchOption), searchOption, token);

            notifier?.UpdateState();
            return(items);
        }
        private string CreateInitializeTempTable(CustomerLedgerSearch option)
        {
            var builder = new StringBuilder();

            builder.Append(@"
IF EXISTS (SELECT * FROM tempdb..sysobjects WHERE id = object_id(N'tempdb..#Ledger'))
    DROP TABLE #Ledger;
CREATE TABLE #Ledger
([CompanyId]        INT                                         NOT NULL
,[ParentCustomerId] INT                                         NOT NULL
,[RecordedAt]       DATETIME2(3)                                NOT NULL
,[DataType]         INT                                         NOT NULL
,[CustomerId]       INT                                         NOT NULL
,[DepartmentId]     INT                                         NOT NULL
,[SectionId]        INT                                         NOT NULL
,[InvoiceCode]      NVARCHAR(100) COLLATE Japanese_CI_AS_KS_WS      NULL
,[CategoryId]       INT                                         NOT NULL
,[AccountTitleId]   INT                                         NOT NULL
,[CurrencyId]       INT                                         NOT NULL
,[BillingInputId]   BIGINT                                          NULL
,[TransactionId]    BIGINT                                          NULL
,[BillingAmount]    NUMERIC(18, 5)                                  NULL
,[ReceiptAmount]    NUMERIC(18, 5)                                  NULL
,[MatchingAmount]   NUMERIC(18, 5)                                  NULL
,[HeaderId1]        BIGINT                                          NULL
,[HeaderId2]        BIGINT                                          NULL
,[HeaderId3]        BIGINT                                          NULL
,[HeaderId4]        BIGINT                                          NULL
,[HeaderId5]        BIGINT                                          NULL
,[HeaderId6]        BIGINT                                          NULL
,[HeaderId7]        BIGINT                                          NULL
);
");
            return(builder.ToString());
        }
        private string CreateSelectLedger(CustomerLedgerSearch option)
        {
            var builder = new StringBuilder();

            builder.Append($@"
SELECT ld.[RecordedAt]
     , ld.[ParentCustomerId]
     , pcs.[Code]   [ParentCustomerCode]
     , pcs.[Name]   [ParentCustomerName]
     , cr.[Code]    [CurrencyCode]
     , ld.[DepartmentId]
     , dp.[Code]    [DepartmentCode]
     , dp.[Name]    [DepartmentName]
     , ld.[SectionId]
     , sc.[Code]    [SectionCode]
     , sc.[Name]    [SectionName]
     , ld.[InvoiceCode]
     , ld.[CategoryId]
     , ct.[Name]    [CategoryName]
     , ld.[AccountTitleId]
     , ac.[Name]    [AccountTitleName]
     , ld.[DataType]
     , ld.[BillingInputId]
     , ld.[TransactionId]
     , ld.[CustomerId]
     , cs.[Code]    [CustomerCode]
     , cs.[Name]    [CustomerName]
     , ld.[BillingAmount]
     , ld.[ReceiptAmount]
     , ld.[MatchingAmount]
     , ld.[HeaderId1], ld.[HeaderId2], ld.[HeaderId3], ld.[HeaderId4], ld.[HeaderId5], ld.[HeaderId6], ld.[HeaderId7]
  FROM #Ledger ld
  LEFT JOIN [dbo].[Customer] pcs
    ON pcs.[Id]     = ld.[ParentCustomerId]
  LEFT JOIN [dbo].[Customer] cs
    ON cs.[Id]      = ld.[CustomerId]
  LEFT JOIN [dbo].[Category] ct
    ON ct.Id        = ld.[CategoryId]
  LEFT JOIN [dbo].[Department] dp
    ON dp.[Id]      = ld.[DepartmentId]
  LEFT JOIN [dbo].[Section] sc
    ON sc.[Id]      = ld.[SectionId]
  LEFT JOIN [dbo].[AccountTitle] ac
    ON ac.[Id]      = ld.[AccountTitleId]
  LEFT JOIN [dbo].[Currency] cr
    ON cr.[Id]      = ld.[CurrencyId]
 ORDER BY
       pcs.[Code]
     , ld.[RecordedAt]
     , ld.[DataType]
     , cs.[Code]
     , ld.[BillingInputId]
     , ld.[TransactionId]
");
            return(builder.ToString());
        }
Example #5
0
 public async Task <CustomerLedgersResult> GetAsync(string SessionKey, CustomerLedgerSearch SearchOption, string connectionId)
 {
     return(await authorizationProcessor.DoAuthorizeAsync(SessionKey, async token =>
     {
         var notifier = hubContext.CreateNotifier(connectionId);
         var result = await customerLedgerProcessor.GetAsync(SearchOption, token, notifier);
         return new CustomerLedgersResult
         {
             ProcessResult = new ProcessResult {
                 Result = true,
             },
             CustomerLedgers = new List <CustomerLedger>(result),
         };
     }, logger, connectionId));
 }
 public Task <IEnumerable <CustomerLedger> > GetAsync(CustomerLedgerSearch searchOption, CancellationToken token, IProgressNotifier notifier)
 {
     return(dbHelper.ExecuteQueriesAsync(async connection =>
     {
         await dbHelper.ExecuteAsync(connection, CreateInitializeTempTable(searchOption), searchOption, token);
         notifier?.UpdateState();
         await dbHelper.ExecuteAsync(connection, CreateInsertBilling(searchOption), searchOption, token);
         notifier?.UpdateState();
         if (searchOption.RequireReceiptData)
         {
             await dbHelper.ExecuteAsync(connection, CreateInsertReceipt(searchOption), searchOption, token);
             notifier?.UpdateState();
         }
         await dbHelper.ExecuteAsync(connection, CreateInsertMatching(searchOption), searchOption, token);
         notifier?.UpdateState();
         var items = await dbHelper.QueryAsync <CustomerLedger>(connection, CreateSelectLedger(searchOption), searchOption, token);
         notifier?.UpdateState();
         return items;
     }));
 }
        private string CreateSelectKeys(CustomerLedgerSearch option)
        {
            var builder = new StringBuilder();

            builder.Append(@"
SELECT COALESCE(pcs.[Id], cs.[Id]) [Key]
     , m2.MatchingHeaderId [Value]
  FROM [dbo].[Billing] b
 INNER JOIN [dbo].[Customer] cs
    ON cs.[Id]          = b.[CustomerId]
   AND b.[CompanyId]    = @CompanyId
   AND b.[CurrencyId]   = @CurrencyId
   AND b.[BilledAt]     < @YearMonthFrom
   AND b.[Approved]     = 1
   AND b.[InputType]   <> 3
   AND (    b.[DeleteAt]     IS NULL
        OR  b.[DeleteAt]     IS NOT NULL AND b.[BillingAmount] <> b.[RemainAmount] )
  LEFT JOIN (
       SELECT b.[Id] [BillingId]
            , SUM( m.[Amount]
                 + m.[BankTransferFee]
                 - CASE WHEN m.[TaxDifference] < 0 THEN m.[TaxDifference] ELSE 0 END
                 + COALESCE( mbd.[DiscountAmount], 0)
                 ) [MatchingAmount]
         FROM [dbo].[Matching] m
        INNER JOIN [dbo].[Billing] b
           ON b.[Id]            = m.[BillingId]
          AND b.[CompanyId]     = @CompanyId
          AND b.[CurrencyId]    = @CurrencyId
          AND m.[RecordedAt]    < @YearMonthFrom
          AND b.[BilledAt]      < @YearMonthFrom
         LEFT JOIN (
              SELECT mbd.[MatchingId]
                   , SUM( mbd.[DiscountAmount] ) [DiscountAmount]
                FROM [dbo].[MatchingBillingDiscount] mbd
               INNER JOIN [dbo].[Matching] m
                  ON m.[Id]             = mbd.[MatchingId]
               INNER JOIN [dbo].[MatchingHeader] mh
                  ON mh.[Id]            = m.[MatchingHeaderId]
                 AND mh.[CompanyId]     = @CompanyId
                 AND mh.[CurrencyId]    = @CurrencyId
               GROUP BY
                     mbd.[MatchingId]
              ) mbd
           ON mbd.[MatchingId]  = m.[Id]
        INNER JOIN [dbo].[Customer] cs
           ON cs.[Id]               = b.[CustomerId]
         LEFT JOIN [dbo].[CustomerGroup] csg
           ON csg.[ChildCustomerId] = b.[CustomerId]
         LEFT JOIN [dbo].[Customer] pcs
           ON pcs.[Id]              = csg.[ParentCustomerId]
        WHERE COALESCE(pcs.[Code], cs.[Code])
                BETWEEN @CustomerCodeFrom AND @CustomerCodeTo");

            if (option.ClosingDay.HasValue)
            {
                builder.Append(@"
          AND COALESCE(pcs.[ClosingDay], cs.[ClosingDay]) = @ClosingDay");
            }

            builder.Append($@"
        GROUP BY
              b.[Id]
       ) m
    ON b.[Id]           = m.[BillingId]
  LEFT JOIN [dbo].[CustomerGroup] csg
    ON csg.[ChildCustomerId]    = b.[CustomerId]
  LEFT JOIN [dbo].[Customer] pcs
    ON pcs.[Id]                 = csg.[ParentCustomerId]
 INNER JOIN [dbo].[Matching] m2
    ON b.[Id]           = m2.[BillingId]
 WHERE COALESCE(pcs.[Code], cs.[Code])
            BETWEEN @CustomerCodeFrom AND @CustomerCodeTo");

            if (option.ClosingDay.HasValue)
            {
                builder.Append(@"
   AND COALESCE(pcs.[ClosingDay], cs.[ClosingDay]) = @ClosingDay");
            }

            builder.Append($@"
   AND b.[BillingAmount]    <> COALESCE(m.[MatchingAmount], 0)
                        + CASE WHEN b.[DeleteAt] IS NULL THEN 0 ELSE b.[RemainAmount] END
 GROUP BY
       COALESCE(pcs.[Id], cs.[Id])
     , m2.MatchingHeaderId
");
            return(builder.ToString());
        }
        private string CreateSelectBalance(CustomerLedgerSearch option)
        {
            var targetDate = option.UseBilledAt ? "b.[BilledAt]" : "b.[SalesAt]";
            var builder    = new StringBuilder();

            builder.Append($@"
SELECT U.[ParentCustomerId] [Key]
     , SUM( U.[CarriedAmount] ) [Value]
  FROM (
        SELECT COALESCE(pcs.[Id], cs.[Id]) [ParentCustomerId]
             , SUM( b.[BillingAmount]
                  - CASE WHEN b.[DeleteAt] IS NULL THEN 0 ELSE b.[RemainAmount] END
                  - COALESCE(m.[MatchingAmount], 0) ) [CarriedAmount]
          FROM [dbo].[Billing] b
         INNER JOIN [dbo].[Customer] cs
            ON cs.[Id]          = b.[CustomerId]
           AND b.[CompanyId]    = @CompanyId
           AND b.[CurrencyId]   = @CurrencyId
           AND {targetDate}     < @YearMonthFrom
           AND b.[Approved]     = 1
           AND b.[InputType]   <> 3
           AND (    b.[DeleteAt]     IS NULL
                OR  b.[DeleteAt]     IS NOT NULL AND b.[BillingAmount] <> b.[RemainAmount] )
          LEFT JOIN (
               SELECT b.[Id] [BillingId]
                    , SUM( m.[Amount]
                         + m.[BankTransferFee]
                         - CASE WHEN m.[TaxDifference] < 0 THEN m.[TaxDifference] ELSE 0 END
                         + COALESCE( mbd.[DiscountAmount], 0)
                         ) [MatchingAmount]
                 FROM [dbo].[Matching] m
                INNER JOIN [dbo].[Billing] b
                   ON b.[Id]            = m.[BillingId]
                  AND b.[CompanyId]     = @CompanyId
                  AND b.[CurrencyId]    = @CurrencyId
                  AND m.[RecordedAt]    < @YearMonthFrom
                  AND {targetDate}      < @YearMonthFrom
                 LEFT JOIN (
                      SELECT mbd.[MatchingId]
                           , SUM( mbd.[DiscountAmount] ) [DiscountAmount]
                        FROM [dbo].[MatchingBillingDiscount] mbd
                       INNER JOIN [dbo].[Matching] m
                          ON m.[Id]             = mbd.[MatchingId]
                       INNER JOIN [dbo].[MatchingHeader] mh
                          ON mh.[Id]            = m.[MatchingHeaderId]
                         AND mh.[CompanyId]     = @CompanyId
                         AND mh.[CurrencyId]    = @CurrencyId
                       GROUP BY
                             mbd.[MatchingId]
                      ) mbd
                   ON mbd.[MatchingId]  = m.[Id]
                INNER JOIN [dbo].[Customer] cs
                   ON cs.[Id]               = b.[CustomerId]
                 LEFT JOIN [dbo].[CustomerGroup] csg
                   ON csg.[ChildCustomerId] = b.[CustomerId]
                 LEFT JOIN [dbo].[Customer] pcs
                   ON pcs.[Id]              = csg.[ParentCustomerId]
                WHERE COALESCE(pcs.[Code], cs.[Code])
                        BETWEEN @CustomerCodeFrom AND @CustomerCodeTo");
            if (option.ClosingDay.HasValue)
            {
                builder.Append(@"
                  AND COALESCE(pcs.[ClosingDay], cs.[ClosingDay]) = @ClosingDay");
            }

            builder.Append($@"
                GROUP BY
                      b.[Id]
               ) m
            ON b.[Id]           = m.[BillingId]
          LEFT JOIN [dbo].[CustomerGroup] csg
            ON csg.[ChildCustomerId]    = b.[CustomerId]
          LEFT JOIN [dbo].[Customer] pcs
            ON pcs.[Id]                 = csg.[ParentCustomerId]
         WHERE COALESCE(pcs.[Code], cs.[Code])
                    BETWEEN @CustomerCodeFrom AND @CustomerCodeTo");

            if (option.ClosingDay.HasValue)
            {
                builder.Append(@"
           AND COALESCE(pcs.[ClosingDay], cs.[ClosingDay]) = @ClosingDay");
            }

            builder.Append($@"
           AND b.[BillingAmount]    <> COALESCE(m.[MatchingAmount], 0)
                                + CASE WHEN b.[DeleteAt] IS NULL THEN 0 ELSE b.[RemainAmount] END
         GROUP BY
               COALESCE(pcs.[Id], cs.[Id])");

            if (option.UseReceipt)
            {
                builder.Append(@"

UNION ALL

        SELECT r.[ParentCustomerId]
             , SUM( r.[MatchingAmount]
                  - CASE r.[ReceiptSeq] WHEN 1 THEN r.[ReceiptAmount] ELSE 0 END ) [CarriedAmount]
          FROM (
                SELECT r.[Id]
                     , ROW_NUMBER() OVER (PARTITION BY r.[Id] ORDER BY m.[MatchingHeaderId], COALESCE(pcs.[Id], cs.[Id]) ) [ReceiptSeq]
                     , MIN( r.[ReceiptAmount] ) [ReceiptAmount]
                     , COALESCE(pcs.[Id], cs.[Id]) [ParentCustomerId]
                     , SUM( CASE WHEN b.[BilledAt] < @YearMonthFrom THEN m.[Amount] ELSE 0 END ) [MatchingAmount]
                  FROM [dbo].[Matching] m
                 INNER JOIN [dbo].[Receipt] r
                    ON r.[Id]           = m.[ReceiptId]
                   AND r.[CompanyId]    = @CompanyId
                   AND r.[CurrencyId]   = @CurrencyId
                   AND r.[RecordedAt]   < @YearMonthFrom
                 INNER JOIN [dbo].[Billing] b
                    ON b.[Id]           = m.[BillingId]
                 INNER JOIN [dbo].[Customer] cs
                    ON cs.[Id]          = b.[CustomerId]
                  LEFT JOIN [dbo].[CustomerGroup] csg
                    ON csg.[ChildCustomerId]    = b.[CustomerId]
                  LEFT JOIN [dbo].[Customer] pcs
                    ON pcs.[Id]         = csg.[ParentCustomerId]
                 WHERE COALESCE(pcs.[Code], cs.[Code])
                        BETWEEN @CustomerCodeFrom AND @CustomerCodeTo");
            }

            if (option.UseReceipt && option.ClosingDay.HasValue)
            {
                builder.Append(@"
                   AND COALESCE(pcs.[ClosingDay], cs.[ClosingDay]) = @ClosingDay");
            }

            if (option.UseReceipt)
            {
                builder.Append($@"
                 GROUP BY r.[Id]
                     , m.[MatchingHeaderId]
                     , COALESCE(pcs.[Id], cs.[Id])
                HAVING MIN( r.[ReceiptAmount] )
                    <> SUM( CASE WHEN b.[BilledAt] < @YearMonthFrom THEN m.[Amount] ELSE 0 END )
               ) r
         GROUP BY
               r.[ParentCustomerId]");
            }

            builder.Append(@"
       ) U
 GROUP BY
       U.ParentCustomerId
 OPTION ( FORCE ORDER )
");
            return(builder.ToString());
        }
        private string CreateInsertMatching(CustomerLedgerSearch option)
        {
            var targetDate = option.UseBilledAt    ? "b.[BilledAt]"            : "b.[SalesAt]";
            var category   = option.DoGroupReceipt ? "r.[ReceiptCategoryId]"   : "MIN( r.[ReceiptCategoryId] )";
            var transId    = option.DoGroupReceipt ? "MIN( r.[Id] )"           : "r.[Id]";
            var partition  = option.DoGroupReceipt ? "r.[ReceiptCategoryId]"   : "r.[Id]";
            var section    = !option.DoGroupReceipt && option.DisplaySection ? "MIN( COALESCE( r.[SectionId], 0 ) )" : "0";
            var recordedAt = $"CASE WHEN m.[RecordedAt] < {targetDate} THEN {targetDate} ELSE m.[RecordedAt] END";
            var builder    = new StringBuilder();

            builder.Append($@"
INSERT INTO #Ledger
([CompanyId]
,[ParentCustomerId]
,[RecordedAt]
,[DataType]
,[CustomerId]
,[DepartmentId]
,[SectionId]
,[InvoiceCode]
,[CategoryId]
,[AccountTitleId]
,[CurrencyId]
,[BillingInputId]
,[TransactionId]
,[MatchingAmount]
,[HeaderId1],[HeaderId2],[HeaderId3],[HeaderId4],[HeaderId5],[HeaderId6],[HeaderId7]
)
SELECT m.[CompanyId]
     , m.[ParentCustomerId]
     , m.[RecordedAt]
     , 3 [DataType]
     , m.[CustomerId]
     , 0 [DepartmentId]
     , m.[SectionId]
     , N'' [InvoiceCode]
     , m.[CategoryId]
     , 0 [AccountTitleId]
     , m.[CurrencyId]
     , 0 [BillingInputId]
     , m.[TransactionId]
     , SUM( m.[MatchingAmount] ) [MatchingAmount]
     , MIN( CASE m.[MatchingSeq] WHEN 1 THEN m.[MatchingHeaderId] ELSE NULL END ) [HeaderId1]
     , MIN( CASE m.[MatchingSeq] WHEN 2 THEN m.[MatchingHeaderId] ELSE NULL END ) [HeaderId2]
     , MIN( CASE m.[MatchingSeq] WHEN 3 THEN m.[MatchingHeaderId] ELSE NULL END ) [HeaderId3]
     , MIN( CASE m.[MatchingSeq] WHEN 4 THEN m.[MatchingHeaderId] ELSE NULL END ) [HeaderId4]
     , MIN( CASE m.[MatchingSeq] WHEN 5 THEN m.[MatchingHeaderId] ELSE NULL END ) [HeaderId5]
     , MIN( CASE m.[MatchingSeq] WHEN 6 THEN m.[MatchingHeaderId] ELSE NULL END ) [HeaderId6]
     , MIN( CASE m.[MatchingSeq] WHEN 7 THEN m.[MatchingHeaderId] ELSE NULL END ) [HeaderId7]
  FROM (
SELECT MIN( r.[CompanyId] ) [CompanyId]
     , MIN( r.[CurrencyId] ) [CurrencyId]
     , COALESCE(pcs.[Id], cs.[Id]) [ParentCustomerId]
     , b.[CustomerId]
     , {transId} [TransactionId]
     , {recordedAt} [RecordedAt]
     , {section} [SectionId]
     , {category} [CategoryId]
     , m.[MatchingHeaderId]
     , SUM( m.[Amount]
          + m.[BankTransferFee]
          - CASE WHEN m.[TaxDifference] < 0 THEN m.[TaxDifference] ELSE 0 END
          + COALESCE( mbd.[DiscountAmount], 0 ) ) [MatchingAmount]
     , ROW_NUMBER() OVER (
        PARTITION BY {partition}, b.[CustomerId], COALESCE(pcs.[Id], cs.[Id]), {recordedAt}
        ORDER BY m.[MatchingHeaderId] ) [MatchingSeq]
  FROM [dbo].[Matching] m
 INNER JOIN [dbo].[Receipt] r
    ON r.[Id]               = m.[ReceiptId]
   AND r.[CompanyId]        = @CompanyId
   AND r.[CurrencyId]       = @CurrencyId
   AND r.[Approved]         = 1
 INNER JOIN [dbo].[Billing] b
    ON b.[Id]               = m.[BillingId]
   AND {recordedAt}
            BETWEEN @YearMonthFrom AND @YearMonthTo
   AND b.[Approved]         = 1
   AND b.[InputType]       <> 3
 INNER JOIN [dbo].[Customer] cs
    ON cs.[Id]              = b.[CustomerId]
  LEFT JOIN (
       SELECT mbd.[MatchingId]
            , SUM( mbd.[DiscountAmount] ) [DiscountAmount]
         FROM [dbo].[MatchingBillingDiscount] mbd
        INNER JOIN [dbo].[Matching] m
           ON m.[Id]            = mbd.[MatchingId]
        INNER JOIN [dbo].[MatchingHeader] mh
           ON mh.[Id]           = m.[MatchingHeaderId]
          AND mh.[CompanyId]    = @CompanyId
          AND mh.[CurrencyId]   = @CurrencyId
        GROUP BY
              mbd.[MatchingId]
       ) mbd
    ON mbd.[MatchingId]     = m.[Id]
  LEFT JOIN [dbo].[CustomerGroup] csg
    ON csg.[ChildCustomerId]    = b.[CustomerId]
  LEFT JOIN [dbo].[Customer] pcs
    ON pcs.[Id]                 = csg.[ParentCustomerId]
 WHERE COALESCE(pcs.[Code], cs.[Code])
            BETWEEN @CustomerCodeFrom AND @CustomerCodeTo");

            if (option.ClosingDay.HasValue)
            {
                builder.Append(@"
   AND COALESCE(pcs.[ClosingDay], cs.[ClosingDay]) = @ClosingDay");
            }

            builder.Append($@"
 GROUP BY
       {partition}, b.[CustomerId], COALESCE(pcs.[Id], cs.[Id]), {recordedAt}
     , m.[MatchingHeaderId]
       ) m
 GROUP BY
       m.[CompanyId], m.[CurrencyId], m.[ParentCustomerId], m.[RecordedAt], m.[CustomerId], m.[SectionId], m.[CategoryId], m.[TransactionId]
 ORDER BY
       [CompanyId], [ParentCustomerId], [RecordedAt], [CustomerId]
OPTION ( FORCE ORDER );
");
            return(builder.ToString());
        }
        private string CreateInsertReceipt(CustomerLedgerSearch option)
        {
            var recordedAt = option.DoGroupReceipt ? "r.[RecordedAt]"          : "MIN( r.[RecordedAt] )";
            var category   = option.DoGroupReceipt ? "r.[ReceiptCategoryId]"   : "MIN( r.[ReceiptCategoryId] )";
            var transId    = option.DoGroupReceipt ? "MIN( r.[Id] )"           : "r.[Id]";
            var partition  = option.DoGroupReceipt ? "r.[RecordedAt], r.[ReceiptCategoryId]" : "r.[Id]";
            var section    = !option.DoGroupReceipt && option.DisplaySection ? "MIN( COALESCE( r.[SectionId], 0 ) )" : "0";
            var builder    = new StringBuilder();

            builder.Append($@"
INSERT INTO #Ledger
([CompanyId]
,[ParentCustomerId]
,[RecordedAt]
,[DataType]
,[CustomerId]
,[DepartmentId]
,[SectionId]
,[InvoiceCode]
,[CategoryId]
,[AccountTitleId]
,[CurrencyId]
,[BillingInputId]
,[TransactionId]
,[ReceiptAmount]
)
SELECT r.[CompanyId]
     , r.[ParentCustomerId]
     , r.[RecordedAt]
     , 2 [DATAKUBUN]
     , r.[CustomerId]
     , 0 [DepartmentId]
     , r.[SectionId]
     , N'' [InvoiceCode]
     , r.[CategoryId]
     , 0 [AccountTitleId]
     , r.[CurrencyId]
     , 0 [BillingInputId]
     , MIN( r.[Transactionid] ) [Transactionid]
     , SUM( CASE r.[ReceiptSeq] WHEN 1 THEN r.[ReceiptAmount] ELSE 0 END
          + r.[MatchingAmount] ) [ReceiptAmount]
  FROM (
SELECT MIN( r.[CompanyId] ) [CompanyId]
     , COALESCE(pcs.[Id], cs.[Id]) [ParentCustomerId]
     , {recordedAt} [RecordedAt]
     , COALESCE(pcs.[Id], cs.[Id]) [CustomerId]
     , {section} [SectionId]
     , {category} [CategoryId]
     , MIN( r.[CurrencyId] ) [CurrencyId]
     , {transId} [Transactionid]
     , ROW_NUMBER() OVER (
            PARTITION BY    {partition}
            ORDER BY        m.[MatchingHeaderId], COALESCE(pcs.[Id], cs.[Id]) ) [ReceiptSeq]
     , MIN( r.[ReceiptAmount] ) [ReceiptAmount]
     , SUM( m.[BankTransferFee]
          - CASE WHEN m.[TaxDifference] < 0 THEN m.[TaxDifference] ELSE 0 END
          + COALESCE( mbd.[DiscountAmount], 0) ) [MatchingAmount]
  FROM [dbo].[Matching] m
 INNER JOIN [dbo].[Receipt] r
    ON r.[Id]           = m.[ReceiptId]
   AND r.[CompanyId]    = @CompanyId
   AND r.[CurrencyId]   = @CurrencyId
   AND r.[RecordedAt]   BETWEEN @YearMonthFrom AND @YearMonthTo
   AND r.[Approved]     = 1
 INNER JOIN [dbo].[Billing] b
    ON b.[Id]           = m.[BillingId]
   AND b.[Approved]     = 1
   AND b.[InputType]   <> 3
 INNER JOIN [dbo].[Customer] cs
    ON cs.[Id]          = b.[CustomerId]
  LEFT JOIN (
       SELECT mbd.[MatchingId]
            , SUM( mbd.[DiscountAmount] ) [DiscountAmount]
         FROM [dbo].[MatchingBillingDiscount] mbd
        INNER JOIN [dbo].[Matching] m
           ON m.[Id]            = mbd.[MatchingId]
        INNER JOIN [dbo].[MatchingHeader] mh
           ON mh.[Id]           = m.[MatchingHeaderId]
          AND mh.[CompanyId]    = @CompanyId
          AND mh.[CurrencyId]   = @CurrencyId
        GROUP BY
              mbd.[MatchingId]
       ) mbd
    ON mbd.[MatchingId] = m.[Id]
  LEFT JOIN [dbo].[CustomerGroup] csg
    ON csg.[ChildCustomerId]    = b.[CustomerId]
  LEFT JOIN [dbo].[Customer] pcs
    ON pcs.[Id]             = csg.[ParentCustomerId]
  LEFT JOIN [dbo].[Matching] om
    ON om.[ReceiptId]       = r.[OriginalReceiptId]
 WHERE COALESCE(pcs.[Code], cs.[Code])
            BETWEEN @CustomerCodeFrom AND @CustomerCodeTo
   AND om.[Id]              IS NULL");

            if (option.ClosingDay.HasValue)
            {
                builder.Append(@"
   AND COALESCE(pcs.[ClosingDay], cs.[ClosingDay]) = @ClosingDay");
            }

            builder.Append($@"
 GROUP BY
       {partition}
     , m.[MatchingHeaderId], COALESCE(pcs.[Id], cs.[Id])
       ) r
 GROUP BY
       [Companyid], [ParentCustomerId], [RecordedAt], [CustomerId], [SectionId], [CategoryId], [CurrencyId]
HAVING SUM( CASE r.[ReceiptSeq] WHEN 1 THEN r.[ReceiptAmount] ELSE 0 END
          + r.[MatchingAmount] ) <> 0
 ORDER BY
       [Companyid], [ParentCustomerId], [RecordedAt], [CustomerId]
 OPTION (FORCE ORDER );
");
            return(builder.ToString());
        }
        private string CreateInsertBilling(CustomerLedgerSearch option)
        {
            var targetDate = option.UseBilledAt                       ? "b.[BilledAt]"            : "b.[SalesAt]";
            var department = option.RequireBillingSubtotal ||
                             option.RequireBillingInputIdSubotal ||
                             !option.DisplayDepartment                            ? "0"                       : "MIN( b.[DepartmentId] )";
            var customer = option.RequireBillingSubtotal            ? "b.[CustomerId]"          : "MIN( b.[CustomerId] )";
            var category = option.RequireBillingCategorySubtotal    ? "b.[BillingCategoryId]"
                             : option.DisplayBillingCategory            ? "MIN( b.[BillingCategoryId] )" : "0";
            var accountTitle = option.RequireDebitAccountTitleSubtotal  ? "COALESCE(b.[DebitAccountTitleId], 0)"
                             : option.DisplayDebitAccountTitle          ? "MIN( COALESCE(b.[DebitAccountTitleId], 0) )" : "0";
            var invoiceCode = option.DisplayInvoiceCode                ? "MIN( b.[InvoiceCode] )"  : "N''";
            var inputId     = option.RequireBillingInputIdSubotal      ? "COALESCE( b.[BillingInputId], b.[Id] )" : "MIN( COALESCE( b.[BillingInputId], b.[Id] ) )";
            var transId     = option.RequireBillingInputIdSubotal || option.RequireBillingSubtotal
                                                                        ? "MIN( b.[Id] )"           : "b.[Id]";
            var recordedAt = option.RequireBillingSubtotal || option.RequireBillingInputIdSubotal
                                                                        ? targetDate                : $"MIN( {targetDate} )";
            var partition
                = option.RequireBillingCategorySubtotal                 ? $"{targetDate}, b.[CustomerId], b.[BillingCategoryId]"
                : option.RequireDebitAccountTitleSubtotal               ? $"{targetDate}, b.[CustomerId], COALESCE(b.[DebitAccountTitleId], 0)"
                : option.RequireBillingInputIdSubotal                   ? $"COALESCE(b.[BillingInputId], b.[Id]), {targetDate}"
                : "b.[Id]";
            var builder = new StringBuilder();

            builder.Append($@"
INSERT INTO #Ledger
([CompanyId]
,[ParentCustomerId]
,[RecordedAt]
,[DataType]
,[CustomerId]
,[DepartmentId]
,[SectionId]
,[InvoiceCode]
,[CategoryId]
,[AccountTitleId]
,[CurrencyId]
,[BillingInputId]
,[TransactionId]
,[BillingAmount]
,[HeaderId1],[HeaderId2],[HeaderId3],[HeaderId4],[HeaderId5],[HeaderId6],[HeaderId7]
)
SELECT W.[CompanyId]
     , W.[ParentCustomerId]
     , W.[RecordedAt]
     , 1  [DataType]
     , W.[CustomerId]
     , W.[DepartmentId]
     , 0  [SectionId]
     , W.[InvoiceCode]
     , W.[CategoryId]
     , W.[AccountTitleId]
     , W.[CurrencyId]
     , W.[BillingInputId]
     , W.[TransactionId]
     , SUM( W.[BillingAmount] ) [BillingAmount]
     , MIN( CASE W.[MatchingSeq] WHEN 1 THEN W.[MatchingHeaderId] ELSE NULL END ) [HeaderId1]
     , MIN( CASE W.[MatchingSeq] WHEN 2 THEN W.[MatchingHeaderId] ELSE NULL END ) [HeaderId2]
     , MIN( CASE W.[MatchingSeq] WHEN 3 THEN W.[MatchingHeaderId] ELSE NULL END ) [HeaderId3]
     , MIN( CASE W.[MatchingSeq] WHEN 4 THEN W.[MatchingHeaderId] ELSE NULL END ) [HeaderId4]
     , MIN( CASE W.[MatchingSeq] WHEN 5 THEN W.[MatchingHeaderId] ELSE NULL END ) [HeaderId5]
     , MIN( CASE W.[MatchingSeq] WHEN 6 THEN W.[MatchingHeaderId] ELSE NULL END ) [HeaderId6]
     , MIN( CASE W.[MatchingSeq] WHEN 7 THEN W.[MatchingHeaderId] ELSE NULL END ) [HeaderId7]
  FROM (
SELECT MIN( b.[CompanyId] ) [CompanyId]
     , COALESCE(pcs.[Id], cs.[Id]) [ParentCustomerId]
     , {recordedAt} [RecordedAt]
     , {customer} [CustomerId]
     , {department} [DepartmentId]
     , {invoiceCode} [InvoiceCode]
     , {category} [CategoryId]
     , {accountTitle} [AccountTitleId]
     , MIN( b.[CurrencyId] ) [CurrencyId]
     , {inputId} [BillingInputId]
     , {transId} [TransactionId]
     , SUM( CASE COALESCE(m.[BillingSeq], 1) WHEN 1
            THEN b.[BillingAmount]
               - CASE WHEN b.[DeleteAt] IS NULL THEN 0 ELSE b.[RemainAmount] END
            ELSE 0 END ) [BillingAmount]
     , m.[MatchingHeaderId]
     , ROW_NUMBER() OVER (PARTITION BY {partition} ORDER BY m.[MatchingHeaderId]) [MatchingSeq]
  FROM [dbo].[Billing] b
 INNER JOIN [dbo].[Customer] cs
    ON cs.[Id]          = b.[CustomerId]
   AND b.[CompanyId]    = @CompanyId
   AND b.[CurrencyId]   = @CurrencyId
   AND {targetDate}     BETWEEN @YearMonthFrom AND @YearMonthTo
   AND b.[Approved]     = 1
   AND b.[InputType]   <> 3
   AND ( b.[DeleteAt]   IS NULL
    OR   b.[DeleteAt]   IS NOT NULL AND b.[RemainAmount] <> b.[BillingAmount] )
  LEFT JOIN (
       SELECT b.[Id] [BillingId]
            , m.[MatchingHeaderId]
            , ROW_NUMBER() OVER (PARTITION BY b.[Id] ORDER BY m.[MatchingHeaderId]) [BillingSeq]
         FROM [dbo].[Matching] m
        INNER JOIN [dbo].[Billing] b
           ON b.[Id]            = m.[BillingId]
          AND b.[CompanyId]     = @CompanyId
          AND b.[CurrencyId]    = @CurrencyId
          AND {targetDate}      BETWEEN @YearMonthFrom AND @YearMonthTo
        INNER JOIN [dbo].[Customer] cs
           ON cs.[Id]           = b.[CustomerId]
         LEFT JOIN [dbo].[CustomerGroup] csg
           ON csg.[ChildCustomerId] = b.[CustomerId]
         LEFT JOIN [dbo].[Customer] pcs
           ON pcs.[Id]          = csg.[ParentCustomerId]
        WHERE COALESCE(pcs.[Code], cs.[Code])
                BETWEEN @CustomerCodeFrom AND @CustomerCodeTo");

            if (option.ClosingDay.HasValue)
            {
                builder.Append(@"
          AND COALESCE(pcs.[ClosingDay], cs.[ClosingDay]) = @ClosingDay");
            }

            builder.Append($@"
        GROUP BY
              b.[Id]
            , m.[MatchingHeaderId]
       ) m
    ON m.[BillingId]    = b.[Id]
  LEFT JOIN [dbo].[CustomerGroup] csg
    ON csg.[ChildCustomerId]    = b.[CustomerId]
  LEFT JOIN [dbo].[Customer] pcs
    ON pcs.[Id]                 = csg.[ParentCustomerId]
 WHERE COALESCE(pcs.[Code], cs.[Code])
            BETWEEN @CustomerCodeFrom AND @CustomerCodeTo");
            if (option.ClosingDay.HasValue)
            {
                builder.Append(@"
   AND COALESCE(pcs.[ClosingDay], cs.[ClosingDay]) = @ClosingDay");
            }

            builder.Append($@"
 GROUP BY {partition}
     , COALESCE(pcs.[Id], cs.[Id])
     , m.[MatchingHeaderId]
       ) W
 GROUP BY [CompanyId], [ParentCustomerId], [RecordedAt], [CustomerId], [DepartmentId], [InvoiceCode], [CategoryId], [AccountTitleId], [CurrencyId], [BillingInputId], [TransactionId]
 ORDER BY
       [CompanyId]
     , [ParentCustomerId]
     , [RecordedAt]
     , [CustomerId]
 OPTION ( FORCE ORDER );
");
            return(builder.ToString());
        }
Example #12
0
 public async Task <ActionResult <IEnumerable <CustomerLedger> > > Get(CustomerLedgerSearch option, CancellationToken token)
 => (await customerLedgerProcessor.GetAsync(option, token, null)).ToArray();
Example #13
0
 public async Task <ActionResult <IEnumerable <CustomerLedger> > > GetR(CustomerLedgerSearch option)
 => await hubContext.DoAsync(option.ConnectionId, async (notifier, token)
                             => (await customerLedgerProcessor.GetAsync(option, token, notifier)).ToArray());
Example #14
0
        public async Task <IEnumerable <CustomerLedger> > GetAsync(CustomerLedgerSearch searchOption, CancellationToken token, IProgressNotifier notifier)
        {
            var ledgers  = (await ledgerQueryProcessor.GetAsync(searchOption, token, notifier)).ToArray();
            var balances = (await ledgerQueryProcessor.GetBalancesAsync(searchOption, token, notifier))
                           .ToDictionary(x => x.Key, x => x.Value);

            SortedList <int, long[]> keys = null;

            if (searchOption.DisplayMatchingSymbol)
            {
                var items = await ledgerQueryProcessor.GetKeysAsync(searchOption, token, notifier);

                keys = new SortedList <int, long[]>(
                    items.GroupBy(x => x.Key)
                    .ToDictionary(x => x.Key, x => x.Select(y => y.Value).ToArray()));
            }
            var         dicKeys        = new Dictionary <long, int>();
            List <long> balanceKeys    = null;
            List <long> currentKeys    = null;
            var         monthlyKeys    = new List <long>();
            var         carryOverKeys  = new List <long>();
            var         symbol         = string.Empty;
            var         carryOverIndex = 0;

            var     balance    = 0M;
            decimal?slipTotal  = null;
            var     closingDay = searchOption.YearMonthTo.Day;

            if (closingDay > 27)
            {
                closingDay = 99;
            }
            DateTime yearMonth;
            var      nextYM    = new DateTime(0);
            var      monthSub  = GetSubtotalList();
            var      parentSub = GetSubtotalList();

            var result = new List <CustomerLedger>();

            var parentCustomerId = 0;

            for (var i = 0; i < ledgers.Length; i++)
            {
                var ledger     = ledgers[i];
                var nextLedger = (i + 1 < ledgers.Length) ? ledgers[i + 1] : null;
                var newParent  = ledger.ParentCustomerId != parentCustomerId;

                ParseYearMonth(ledger, closingDay, out yearMonth);
                ledger.YearMonth = yearMonth;
                if (newParent)
                {
                    if (searchOption.DisplayMatchingSymbol)
                    {
                        balanceKeys = keys.ContainsKey(ledger.ParentCustomerId)
                            ? keys[ledger.ParentCustomerId].ToList() : new List <long>();
                        monthlyKeys.Clear();
                        carryOverKeys.Clear();
                    }
                    balance = balances.ContainsKey(ledger.ParentCustomerId)
                        ? balances[ledger.ParentCustomerId] : 0M;
                    var carryOver = new CustomerLedger();
                    carryOver.ParentCustomerId   = ledger.ParentCustomerId;
                    carryOver.ParentCustomerCode = ledger.ParentCustomerCode;
                    carryOver.ParentCustomerName = ledger.ParentCustomerName;
                    carryOver.CurrencyCode       = ledger.CurrencyCode;
                    carryOver.RecordType         = CustomerLedger.RecordTypeAlias.CarryOverRecord;
                    carryOver.YearMonth          = yearMonth;
                    carryOver.RemainAmount       = balance;
                    result.Add(carryOver);
                    if (searchOption.DisplayMatchingSymbol)
                    {
                        carryOverIndex = result.IndexOf(carryOver);
                    }
                }

                parentCustomerId = ledger.ParentCustomerId;

                if (searchOption.DisplaySlipTotal &&
                    ledger.DataType == 1 &&
                    ledger.BillingAmount.HasValue)
                {
                    slipTotal = (slipTotal ?? 0M) + ledger.BillingAmount.Value;
                }
                var setSlipTotal = searchOption.DisplaySlipTotal && ledger.DataType == 1 &&
                                   (nextLedger == null ||
                                    ledger.DataType != nextLedger.DataType ||
                                    ledger.BillingInputId != nextLedger.BillingInputId ||
                                    ledger.RecordedAt != nextLedger.RecordedAt);

                if (searchOption.DisplayMatchingSymbol && ledger.DataType != 2)
                {
                    currentKeys = ledger.GetKeys();
                    ConvertKeysToSymbols(dicKeys, currentKeys, ref symbol);
                }
                if (ledger.DataType == 1 && ledger.BillingAmount.HasValue)
                {
                    balance += ledger.BillingAmount.Value;
                }
                if (ledger.DataType == 2 && ledger.ReceiptAmount.HasValue && searchOption.UseReceipt)
                {
                    balance -= ledger.ReceiptAmount.Value;
                }
                if (ledger.DataType == 3 && ledger.MatchingAmount.HasValue && !searchOption.UseReceipt)
                {
                    balance -= ledger.MatchingAmount.Value;
                }

                if (setSlipTotal)
                {
                    ledger.SlipTotal = slipTotal;
                    slipTotal        = null;
                }
                AddSubtotal(monthSub, ledger);
                AddSubtotal(parentSub, ledger);

                if (ledger.DataType == 1 && (!searchOption.DisplaySlipTotal || setSlipTotal) ||
                    ledger.DataType == 2 && searchOption.UseReceipt ||
                    ledger.DataType == 3 && !searchOption.UseReceipt)
                {
                    ledger.RemainAmount = balance;
                }

                if (searchOption.DisplayMatchingSymbol)
                {
                    if (ledger.DataType == 1)
                    {
                        ledger.MatchingSymbolBilling = symbol;
                        foreach (var key in currentKeys)
                        {
                            if (!balanceKeys.Contains(key) &&
                                !monthlyKeys.Contains(key))
                            {
                                monthlyKeys.Add(key);
                            }
                        }
                    }
                    if (ledger.DataType == 3)
                    {
                        ledger.MatchingSymbolReceipt = symbol;
                        foreach (var key in currentKeys)
                        {
                            if (balanceKeys.Contains(key) &&
                                !carryOverKeys.Contains(key))
                            {
                                carryOverKeys.Add(key);
                            }
                        }
                    }
                }
                ledger.RecordType = CustomerLedger.RecordTypeAlias.DataRecord;
                ledger.Truncate(searchOption.UnitPrice);
                result.Add(ledger);

                var sameYM     = IsSameYearMonth(yearMonth, nextLedger, closingDay, out nextYM);
                var sameParent = nextLedger?.ParentCustomerId == ledger.ParentCustomerId;


                if (!sameYM)
                {
                    var sub = new CustomerLedger();
                    sub.ParentCustomerId   = ledger.ParentCustomerId;
                    sub.ParentCustomerCode = ledger.ParentCustomerCode;
                    sub.ParentCustomerName = ledger.ParentCustomerName;
                    sub.CurrencyCode       = ledger.CurrencyCode;
                    sub.YearMonth          = yearMonth;
                    sub.RecordType         = CustomerLedger.RecordTypeAlias.MonthlySubtotalRecord;
                    sub.RemainAmount       = balance;
                    //sub.Caption = $"{yearMont:MM}月合計";
                    SetSubtotal(monthSub, sub);
                    ClearSubtotal(monthSub);
                    sub.Truncate(searchOption.UnitPrice);
                    result.Add(sub);
                }

                if (!sameYM && sameParent &&
                    searchOption.IsPrint && searchOption.RequireMonthlyBreak)
                {
                    var carryOver = new CustomerLedger();
                    carryOver.ParentCustomerId   = ledger.ParentCustomerId;
                    carryOver.ParentCustomerCode = ledger.ParentCustomerCode;
                    carryOver.ParentCustomerName = ledger.ParentCustomerName;
                    carryOver.CurrencyCode       = ledger.CurrencyCode;
                    carryOver.YearMonth          = nextYM;
                    carryOver.RecordType         = CustomerLedger.RecordTypeAlias.CarryOverRecord;
                    carryOver.RemainAmount       = balance;
                    //carryOver.Caption = "繰越";
                    carryOver.Truncate(searchOption.UnitPrice);
                    result.Add(carryOver);
                    if (searchOption.DisplayMatchingSymbol)
                    {
                        ConvertKeysToSymbols(dicKeys, carryOverKeys, ref symbol);
                        result[carryOverIndex].MatchingSymbolBilling = symbol;

                        foreach (var key in monthlyKeys)
                        {
                            if (!balanceKeys.Contains(key))
                            {
                                balanceKeys.Add(key);
                            }
                        }
                        monthlyKeys.Clear();
                        carryOverKeys.Clear();
                        carryOverIndex = result.IndexOf(carryOver);
                    }
                }

                if (!sameParent)
                {
                    var sub = new CustomerLedger();
                    sub.ParentCustomerId   = ledger.ParentCustomerId;
                    sub.ParentCustomerCode = ledger.ParentCustomerCode;
                    sub.ParentCustomerName = ledger.ParentCustomerName;
                    sub.CurrencyCode       = ledger.CurrencyCode;
                    sub.YearMonth          = yearMonth;
                    sub.RecordType         = CustomerLedger.RecordTypeAlias.TotalRecord;
                    sub.RemainAmount       = balance;
                    //sub.Caption = "総合計";
                    SetSubtotal(parentSub, sub);
                    ClearSubtotal(parentSub);
                    sub.Truncate(searchOption.UnitPrice);
                    result.Add(sub);
                    if (searchOption.DisplayMatchingSymbol)
                    {
                        ConvertKeysToSymbols(dicKeys, carryOverKeys, ref symbol);
                        result[carryOverIndex].MatchingSymbolBilling = symbol;
                    }
                }
            }
            notifier?.UpdateState();
            return(result);
        }