packages feed

ochintin-daicho (empty) → 0.1.0.0

raw patch · 7 files changed

+570/−0 lines, 7 filesdep +Globdep +basedep +bookkeepingsetup-changed

Dependencies added: Glob, base, bookkeeping, doctest, ochintin-daicho, text

Files

+ LICENSE view
@@ -0,0 +1,21 @@+MIT License++Copyright (c) 2017 Kadzuya OKAMOTO, http://www.arow.info++Permission is hereby granted, free of charge, to any person obtaining a copy+of this software and associated documentation files (the "Software"), to deal+in the Software without restriction, including without limitation the rights+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell+copies of the Software, and to permit persons to whom the Software is+furnished to do so, subject to the following conditions:++The above copyright notice and this permission notice shall be included in all+copies or substantial portions of the Software.++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE+SOFTWARE.
+ README.md view
@@ -0,0 +1,17 @@+[![Build Status](https://travis-ci.org/arowM/haskell-ochinchin-daicho.svg?branch=master)](https://travis-ci.org/arowM/haskell-ochinchin-daicho)+[![Hackage](https://img.shields.io/hackage/v/ochinchin-daicho.svg)](https://hackage.haskell.org/package/ochinchin-daicho)+[![Stackage LTS](http://stackage.org/package/ochinchin-daicho/badge/lts)](http://stackage.org/lts/package/ochinchin-daicho)+[![Stackage Nightly](http://stackage.org/package/ochinchin-daicho/badge/nightly)](http://stackage.org/nightly/package/ochinchin-daicho)++# Haskell-ochinchin-daicho++A module to manage payroll books for Japanese companies.++おちんぎん台帳をHaskellで記述して管理できるモジュール。+源泉徴収簿や仕訳帳として出力できて Single source of truth な感じ。++## Build++```bash+$ stack build+```
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ ochintin-daicho.cabal view
@@ -0,0 +1,51 @@+name:                ochintin-daicho+version:             0.1.0.0+synopsis:            A module to manage payroll books for Japanese companies.+description:+    A module to manage payroll books for Japanese companies. This enable to export data to tax withholding book, etc...+homepage:            https://github.com/arowM/haskell-ochintin-daicho#readme+license:             MIT+license-file:        LICENSE+author:              Kadzuya Okamoto+maintainer:          arow.okamoto+github@gmail.com+copyright:           2017 Kadzuya Okamoto+category:            Business+build-type:          Simple+extra-source-files:  README.md+cabal-version:       >=1.10++library+  hs-source-dirs:      src+  exposed-modules:     Business.OchintinDaicho+  build-depends:       base >= 4.9 && < 5+                     , bookkeeping >= 0.2.1.4+                     , text >= 1.2.2.1+  default-language:    Haskell2010+  ghc-options:         -Wall -Wincomplete-uni-patterns -Wincomplete-record-updates+  default-extensions:  OverloadedStrings+                     , RecordWildCards+  other-extensions:    GeneralizedNewtypeDeriving++test-suite ochintin-daicho-test+  type:                exitcode-stdio-1.0+  hs-source-dirs:      test+  main-is:             Spec.hs+  build-depends:       base+                     , ochintin-daicho+  ghc-options:         -threaded -rtsopts -with-rtsopts=-N+  default-language:    Haskell2010++test-suite doctest+  type:                exitcode-stdio-1.0+  hs-source-dirs:      test+  main-is:             Doctest.hs+  build-depends:       base+                     , Glob+                     , doctest >= 0.10+                     , ochintin-daicho+  ghc-options:         -threaded -rtsopts -with-rtsopts=-N+  default-language:    Haskell2010++source-repository head+  type:     git+  location: https://github.com/arowM/haskell-ochintin-daicho
+ src/Business/OchintinDaicho.hs view
@@ -0,0 +1,458 @@+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE Strict #-}+{-# LANGUAGE StrictData #-}++{- |+Module      :  Business.OchintinDaicho++Copyright   :  Kadzuya Okamoto 2017+License     :  MIT++Stability   :  experimental+Portability :  unknown++This module exports core functions and types for payroll books.+-}+module Business.OchintinDaicho+  (+  -- * Usage examples+  -- $setup++  -- * Types+    Person(..)+  , Payment(..)+  , Payments+  , Hours++  -- * Pretty printers+  , ppr++  -- * Converters+  , toBookkeeping++  -- * Convenient functions for 年末調整+  , _年度内課税支給金額+  , _年度内社会保険控除額+  , _年度内所得税控除額+  ) where++import Business.Bookkeeping+       (Amount(..), Category(..), CategoryType(..), CreditCategory(..), Date(..),+        DateTransactions, DebitCategory(..), Month(..), Transaction,+        Transactions, Year(..), activity, dateTrans, month, runTransactions, tAmount,+        year)+import Control.Monad (forM_)+import Data.Monoid ((<>))+import Data.Text (Text)+import qualified Data.Text as T+import qualified Data.Text.IO as T+import Data.String (IsString(..))+++{- $setup+>>> import Business.Bookkeeping hiding (ppr)+>>> :{+let+  taroYamada :: Person+  taroYamada = Person+    { name = "山田 太郎"+    , sex = "男"+    , payments = \y -> case y of+      2017 ->+        [ ( (1, 10)+          , Payment+            { _賃金計算期間 = (2016, 12)+            , _労働日数 = 13+            , _労働時間数 = 13 * 5+            , _休日労働時間数 = 0+            , _早出残業時間数 = 0+            , _深夜労働時間数 = 0+            , _課税支給額 = 250000+            , _控除社会保険料 = \debit amount -> do+              dateTrans debit+                (CreditCategory $ Category "預り金" Liabilities)+                "健康保険料(社員負担分)"+                $ if (200000 < amount && amount < 300000)+                  then 15000+                  else error "undefined 健康保険料"+              dateTrans debit+                (CreditCategory $ Category "預り金" Liabilities)+                "厚生年金(社員負担分)"+                $ if (200000 < amount && amount < 300000)+                  then 20000+                  else error "undefined 厚生年金"+              dateTrans debit+                (CreditCategory $ Category "預り金" Liabilities)+                "雇用保険料(社員負担分)"+                $ if (200000 < amount && amount < 300000)+                  then 1000+                  else error "undefined 雇用保険料"+            , _所得税額 = \debit amount ->+              dateTrans debit+                (CreditCategory $ Category "預り金" Liabilities)+                "源泉所得税"+                $ if (200000 < amount && amount < 250000)+                  then 5000+                  else error $ "undefined 所得税額 for " <> show amount+            , _非課税支給額 = \credit -> do+              dateTrans+                (DebitCategory $ Category "旅費・交通費" Expenses)+                credit+                "立替交通費"+                3000+            , _その他控除 = \debit ->+              dateTrans debit+                (CreditCategory $ Category "預り金" Liabilities)+                "親睦会費"+                5000+            }+          )+        , ( (2, 10)+          , Payment+            { _賃金計算期間 = (2017, 1)+            , _労働日数 = 12+            , _労働時間数 = 12 * 5+            , _休日労働時間数 = 0+            , _早出残業時間数 = 0+            , _深夜労働時間数 = 0+            , _課税支給額 = 250000+            , _控除社会保険料 = \debit amount -> do+              dateTrans debit+                (CreditCategory $ Category "預り金" Liabilities)+                "健康保険料(社員負担分)"+                $ if (200000 < amount && amount < 300000)+                  then 15000+                  else error "undefined 健康保険料"+              dateTrans debit+                (CreditCategory $ Category "預り金" Liabilities)+                "厚生年金(社員負担分)"+                $ if (200000 < amount && amount < 300000)+                  then 20000+                  else error "undefined 厚生年金"+              dateTrans debit+                (CreditCategory $ Category "預り金" Liabilities)+                "雇用保険料(社員負担分)"+                $ if (200000 < amount && amount < 300000)+                  then 1000+                  else error "undefined 雇用保険料"+            , _所得税額 = \debit amount ->+              dateTrans debit+                (CreditCategory $ Category "預り金" Liabilities)+                "源泉所得税"+                $ if (200000 < amount && amount < 250000)+                  then 5000+                  else error $ "undefined 所得税額2 for " <> show amount+            , _非課税支給額 = \credit -> do+              dateTrans+                (DebitCategory $ Category "旅費・交通費" Expenses)+                credit+                "立替交通費"+                4000+            , _その他控除 = \debit ->+              dateTrans debit+                (CreditCategory $ Category "預り金" Liabilities)+                "親睦会費"+                5000+            }+          )+        ]+      _ ->+        []+    }+:}+-}++{-| 対象年度内の課税支給額総計++>>> _年度内課税支給金額 taroYamada 2017+Amount {unAmount = 500000}+-}+_年度内課税支給金額 :: Person -> Year -> Amount+_年度内課税支給金額 Person {..} =+  sum . map (_課税支給額 . snd) . payments++{-| 対象年度内の社会保険料等控除額総計++>>> _年度内社会保険控除額 taroYamada 2017+Amount {unAmount = 72000}+-}+_年度内社会保険控除額 :: Person -> Year -> Amount+_年度内社会保険控除額 Person {..} =+  sum . map (_算出保険料 . snd) . payments++{-| 対象年度内の所得税控除額総計++>>> _年度内所得税控除額 taroYamada 2017+Amount {unAmount = 10000}+-}+_年度内所得税控除額 :: Person -> Year -> Amount+_年度内所得税控除額 Person {..} =+  sum . map (_算出所得税 . snd) . payments++{-| A pretty printer for payroll books.++>>> ppr taroYamada 2017+氏名: 山田 太郎+性別: 男+<BLANKLINE>+== 2017年支給分 ==+<BLANKLINE>+支給日: 1月10日+賃金計算期間: 2016年12月+労働日数: 13日+労働時間数: 65時間+休日労働時間数: 0時間+早出残業時間数: 0時間+深夜労働時間数: 0時間+課税支給額: 250000円+控除社会保険料: 36000円+社会保険料等控除の金額: 214000円+所得税額: 5000円+非課税支給額: 3000円+その他控除: 5000円+--> 実支払額: 207000円+<BLANKLINE>+支給日: 2月10日+賃金計算期間: 2017年1月+労働日数: 12日+労働時間数: 60時間+休日労働時間数: 0時間+早出残業時間数: 0時間+深夜労働時間数: 0時間+課税支給額: 250000円+控除社会保険料: 36000円+社会保険料等控除の金額: 214000円+所得税額: 5000円+非課税支給額: 4000円+その他控除: 5000円+--> 実支払額: 208000円+<BLANKLINE>+-}+ppr :: Person -> Year -> IO ()+ppr Person {..} y = do+  T.putStrLn $ "氏名: " <> name+  T.putStrLn $ "性別: " <> sex+  T.putStrLn ""+  T.putStrLn . T.concat $+    [ "== "+    , tshow . unYear $ y+    , "年支給分 =="+    ]+  T.putStrLn ""+  forM_ (payments y) $ \((m, d), payment@(Payment {..})) -> do+    let+      (targetYear, targetMonth) = _賃金計算期間+      _算出保険料' = _算出保険料 payment+      _算出所得税' = _算出所得税 payment+      _非課税支給額総計' = _非課税支給額総計 payment+      _その他控除総計' = _その他控除総計 payment+      _実支払額' = _実支払額 payment+    T.putStrLn $ "支給日: " <> (tshow . unMonth) m <> "月" <> (tshow . unDate) d <> "日"+    T.putStrLn $ "賃金計算期間: " <> (tshow . unYear) targetYear <> "年" <> (tshow . unMonth) targetMonth <> "月"+    T.putStrLn $ "労働日数: " <> tshow _労働日数 <> "日"+    T.putStrLn $ "労働時間数: " <> (tshowIntegral) _労働時間数 <> "時間"+    T.putStrLn $ "休日労働時間数: " <> (tshowIntegral) _休日労働時間数 <> "時間"+    T.putStrLn $ "早出残業時間数: " <> (tshowIntegral) _早出残業時間数 <> "時間"+    T.putStrLn $ "深夜労働時間数: " <> (tshowIntegral) _深夜労働時間数 <> "時間"+    T.putStrLn $ "課税支給額: " <> (tshow . unAmount) _課税支給額 <> "円"+    T.putStrLn $ "控除社会保険料: " <> (tshow . unAmount) _算出保険料' <> "円"+    T.putStrLn $ "社会保険料等控除の金額: " <> (tshow . unAmount) (_課税支給額 - _算出保険料') <> "円"+    T.putStrLn $ "所得税額: " <> (tshow . unAmount) _算出所得税' <> "円"+    T.putStrLn $ "非課税支給額: " <> (tshow . unAmount) _非課税支給額総計' <> "円"+    T.putStrLn $ "その他控除: " <> (tshow . unAmount) _その他控除総計' <> "円"+    T.putStrLn $ "--> 実支払額: " <> (tshow . unAmount) _実支払額' <> "円"+    T.putStrLn ""++{-|++>>> :{+Business.Bookkeeping.ppr $ toBookkeeping taroYamada 2017+  (DebitCategory $ Category "給与手当" Expenses)+  (CreditCategory $ Category "普通預金" Liabilities)+:}+tDay: 2017-01-10+tDescription: 12月度+tSubDescription: 立替交通費+tDebit: 旅費・交通費 (Expenses)+tCredit: 普通預金 (Liabilities)+tAmount: 3000+<BLANKLINE>+tDay: 2017-01-10+tDescription: 12月度+tSubDescription: 健康保険料(社員負担分)+tDebit: 給与手当 (Expenses)+tCredit: 預り金 (Liabilities)+tAmount: 15000+<BLANKLINE>+tDay: 2017-01-10+tDescription: 12月度+tSubDescription: 厚生年金(社員負担分)+tDebit: 給与手当 (Expenses)+tCredit: 預り金 (Liabilities)+tAmount: 20000+<BLANKLINE>+tDay: 2017-01-10+tDescription: 12月度+tSubDescription: 雇用保険料(社員負担分)+tDebit: 給与手当 (Expenses)+tCredit: 預り金 (Liabilities)+tAmount: 1000+<BLANKLINE>+tDay: 2017-01-10+tDescription: 12月度+tSubDescription: 源泉所得税+tDebit: 給与手当 (Expenses)+tCredit: 預り金 (Liabilities)+tAmount: 5000+<BLANKLINE>+tDay: 2017-01-10+tDescription: 12月度+tSubDescription: 親睦会費+tDebit: 給与手当 (Expenses)+tCredit: 預り金 (Liabilities)+tAmount: 5000+<BLANKLINE>+tDay: 2017-01-10+tDescription: 12月度+tSubDescription: 給与支払い+tDebit: 給与手当 (Expenses)+tCredit: 普通預金 (Liabilities)+tAmount: 207000+<BLANKLINE>+tDay: 2017-02-10+tDescription: 1月度+tSubDescription: 立替交通費+tDebit: 旅費・交通費 (Expenses)+tCredit: 普通預金 (Liabilities)+tAmount: 4000+<BLANKLINE>+tDay: 2017-02-10+tDescription: 1月度+tSubDescription: 健康保険料(社員負担分)+tDebit: 給与手当 (Expenses)+tCredit: 預り金 (Liabilities)+tAmount: 15000+<BLANKLINE>+tDay: 2017-02-10+tDescription: 1月度+tSubDescription: 厚生年金(社員負担分)+tDebit: 給与手当 (Expenses)+tCredit: 預り金 (Liabilities)+tAmount: 20000+<BLANKLINE>+tDay: 2017-02-10+tDescription: 1月度+tSubDescription: 雇用保険料(社員負担分)+tDebit: 給与手当 (Expenses)+tCredit: 預り金 (Liabilities)+tAmount: 1000+<BLANKLINE>+tDay: 2017-02-10+tDescription: 1月度+tSubDescription: 源泉所得税+tDebit: 給与手当 (Expenses)+tCredit: 預り金 (Liabilities)+tAmount: 5000+<BLANKLINE>+tDay: 2017-02-10+tDescription: 1月度+tSubDescription: 親睦会費+tDebit: 給与手当 (Expenses)+tCredit: 預り金 (Liabilities)+tAmount: 5000+<BLANKLINE>+tDay: 2017-02-10+tDescription: 1月度+tSubDescription: 給与支払い+tDebit: 給与手当 (Expenses)+tCredit: 普通預金 (Liabilities)+tAmount: 208000+<BLANKLINE>++-}+toBookkeeping :: Person -> Year -> DebitCategory -> CreditCategory -> Transactions+toBookkeeping Person {..} y debit credit =+  year y $+    forM_ (payments y) $ \((m, d), payment@(Payment {..})) -> do+      let+        (_, targetMonth) = _賃金計算期間+        _算出保険料' = _算出保険料 payment+        _算出所得税' = _算出所得税 payment+        _非課税支給額総計' = _非課税支給額総計 payment+        _その他控除総計' = _その他控除総計 payment+        _実支払額' = _実支払額 payment+      month m $+        activity d (fromString $ (show . unMonth) targetMonth <> "月度") $ do+          _非課税支給額 credit+          _控除社会保険料 debit _課税支給額+          _所得税額 debit (_課税支給額 - _算出保険料')+          _その他控除 debit+          dateTrans debit credit "給与支払い" _実支払額'+++{- ==============+ -     Types+ - ============== -}++{-| Main data type to represent payroll books for a person.+ -}+data Person = Person+  { name :: Text+  , sex :: Text+  , payments :: Year -> Payments+  }++{-| A type for handling `Payment` values.+ -}+type Payments = [((Month, Date), Payment)]++data Payment = Payment+  { _賃金計算期間 :: (Year, Month)+  , _労働日数 :: Int+  , _労働時間数 :: Hours+  , _休日労働時間数 :: Hours+  , _早出残業時間数 :: Hours+  , _深夜労働時間数 :: Hours+  , _課税支給額 :: Amount+  , _非課税支給額 :: CreditCategory -> DateTransactions+  , _控除社会保険料 :: DebitCategory -> Amount -> DateTransactions+  , _所得税額 :: DebitCategory -> Amount -> DateTransactions+  , _その他控除 :: DebitCategory -> DateTransactions+  }++newtype Hours = Hours { _unHours :: Int }+  deriving (Show, Read, Ord, Eq, Num, Enum, Integral, Real)+++-- Helper functions+tshow :: (Show a) => a -> T.Text+tshow = T.pack . show+++tshowIntegral :: (Integral a) => a -> T.Text+tshowIntegral a = T.pack . show $ (fromIntegral a :: Int)+++dummyDebit :: DebitCategory+dummyDebit = DebitCategory $ Category "DUMMY!" Expenses++dummyCredit :: CreditCategory+dummyCredit = CreditCategory $ Category "DUMMY!" Liabilities++_算出保険料 :: Payment -> Amount+_算出保険料 Payment {..} = sum . map tAmount . runDummyActivity $ _控除社会保険料 dummyDebit _課税支給額++_算出所得税 :: Payment -> Amount+_算出所得税 payment@(Payment {..}) = sum . map tAmount . runDummyActivity $ _所得税額 dummyDebit (_課税支給額 - _算出保険料 payment)++_非課税支給額総計 :: Payment -> Amount+_非課税支給額総計 Payment {..} = sum . map tAmount . runDummyActivity $ _非課税支給額 dummyCredit++_その他控除総計 :: Payment -> Amount+_その他控除総計 Payment {..} = sum . map tAmount . runDummyActivity $ _その他控除 dummyDebit++_実支払額 :: Payment -> Amount+_実支払額 payment@(Payment {..}) = _課税支給額 - _算出保険料 payment - _算出所得税 payment - _その他控除総計 payment + _非課税支給額総計 payment++runDummyActivity :: DateTransactions -> [Transaction]+runDummyActivity = runTransactions . year 1 . month 1 . activity 1 ""
+ test/Doctest.hs view
@@ -0,0 +1,19 @@+module Main where++import Data.Monoid ((<>))+import System.FilePath.Glob (glob)+import Test.DocTest (doctest)++main :: IO ()+main = glob "src/**/*.hs" >>= doDocTest++doDocTest :: [String] -> IO ()+doDocTest options = doctest $ options <> ghcExtensions++ghcExtensions :: [String]+ghcExtensions =+    [ "-XOverloadedStrings"+    , "-XRecordWildCards"+    , "-XStrict"+    , "-XStrictData"+    ]
+ test/Spec.hs view
@@ -0,0 +1,2 @@+main :: IO ()+main = putStrLn "Test suite not yet implemented"