5555
5656 docOpenNoBrowser bool
5757
58+ docDocviewFormCode string
59+ docDocviewFormName string
60+ docDocviewRouteCode string
61+ docDocviewFromDocID int
62+ docDocviewProxyUser string
63+ docDocviewOutput string
64+
65+ docDocviewUploadFormCode string
66+ docDocviewUploadFormName string
67+ docDocviewUploadRouteCode string
68+ docDocviewUploadFromDocID int
69+ docDocviewUploadProxyUser string
70+ docDocviewUploadDatas string
71+ docDocviewUploadFile string
72+ docDocviewUploadFileName string
73+ docDocviewUploadRemarks string
74+ docDocviewUploadDetailNo int
75+ docDocviewUploadEvidenceType int
76+ docDocviewUploadOutput string
77+
78+ docOpenviewProxyUser string
79+ docOpenviewOutput string
80+
81+ docStatusviewOutput string
82+
5883 docCommentAddContent string
5984 docCommentAddAttention bool
6085 docCommentAddOutput string
@@ -226,6 +251,59 @@ By default the command prompts for confirmation. Pass --yes to skip it.`,
226251 RunE : runDocumentCommentDelete ,
227252}
228253
254+ var documentDocviewCmd = & cobra.Command {
255+ Use : "docview" ,
256+ Short : "Fetch the HTML view for creating a new document or a related document" ,
257+ Long : `Fetch the HTML form used to create a new document or a related document via
258+ GET /api/v1/documents/docview.
259+
260+ Specify the target form with either --form-code or --form-name (form name takes
261+ priority on the server side if both are given). --route-code is required; pass
262+ an empty string ("") for standard forms or "--condroute" for workflow forms
263+ with auto-select routes.
264+
265+ By default the HTML is saved to a file named like "docview-<fcd|formname>.html"
266+ in the current directory. Use --output to override:
267+ --output FILE save to FILE
268+ --output DIR/ save into DIR/ using the default filename
269+ --output - write the HTML to stdout` ,
270+ Args : cobra .NoArgs ,
271+ RunE : runDocumentDocview ,
272+ }
273+
274+ var documentDocviewUploadCmd = & cobra.Command {
275+ Use : "docview-upload" ,
276+ Short : "Fetch the HTML form for a new document with pre-filled data or attachment (multipart)" ,
277+ Long : `Fetch the HTML form for creating a new document or a related document with
278+ pre-filled field values and/or a pre-attached file via POST
279+ /multiapi/v1/documents/docview.
280+
281+ Specify the target form with either --form-code or --form-name. --route-code
282+ is required. Pass --datas to supply pre-fill JSON, and --file to attach a
283+ single file (--file-name defaults to basename of --file).` ,
284+ Args : cobra .NoArgs ,
285+ RunE : runDocumentDocviewUpload ,
286+ }
287+
288+ var documentOpenviewCmd = & cobra.Command {
289+ Use : "openview <docid>" ,
290+ Short : "Fetch the HTML view of a document" ,
291+ Long : `Fetch the HTML view of a document via GET /api/v1/documents/{docid}/openview.
292+
293+ The HTML is the same rendering as the X-point viewer but cannot be closed by
294+ the in-page close button (use the browser tab/window close instead).` ,
295+ Args : cobra .ExactArgs (1 ),
296+ RunE : runDocumentOpenview ,
297+ }
298+
299+ var documentStatusviewCmd = & cobra.Command {
300+ Use : "statusview <docid>" ,
301+ Short : "Fetch the HTML of the approval status view" ,
302+ Long : "Fetch the HTML of the approval status view via GET /api/v1/documents/{docid}/statusview." ,
303+ Args : cobra .ExactArgs (1 ),
304+ RunE : runDocumentStatusview ,
305+ }
306+
229307var documentDownloadCmd = & cobra.Command {
230308 Use : "download <docid>" ,
231309 Short : "Download a document as PDF" ,
@@ -249,6 +327,10 @@ func init() {
249327 documentCmd .AddCommand (documentDeleteCmd )
250328 documentCmd .AddCommand (documentStatusCmd )
251329 documentCmd .AddCommand (documentDownloadCmd )
330+ documentCmd .AddCommand (documentDocviewCmd )
331+ documentCmd .AddCommand (documentDocviewUploadCmd )
332+ documentCmd .AddCommand (documentOpenviewCmd )
333+ documentCmd .AddCommand (documentStatusviewCmd )
252334 documentCmd .AddCommand (documentOpenCmd )
253335 documentCmd .AddCommand (documentCommentCmd )
254336 documentCommentCmd .AddCommand (documentCommentAddCmd )
@@ -302,6 +384,35 @@ func init() {
302384 of := documentOpenCmd .Flags ()
303385 of .BoolVarP (& docOpenNoBrowser , "no-browser" , "n" , false , "print the URL without launching the browser" )
304386
387+ dvf := documentDocviewCmd .Flags ()
388+ dvf .StringVar (& docDocviewFormCode , "form-code" , "" , "form code (fcd); use --form-name instead or in addition (form-name wins)" )
389+ dvf .StringVar (& docDocviewFormName , "form-name" , "" , "form name" )
390+ dvf .StringVar (& docDocviewRouteCode , "route-code" , "" , "approval route code (required; \" \" for standard forms, \" --condroute\" for auto-select workflow routes)" )
391+ dvf .IntVar (& docDocviewFromDocID , "from-docid" , 0 , "source document ID for a related document (0 = omit)" )
392+ dvf .StringVar (& docDocviewProxyUser , "proxy-user" , "" , "proxy applicant user code (代理申請)" )
393+ dvf .StringVarP (& docDocviewOutput , "output" , "o" , "" , "output path: FILE, DIR/, or - for stdout (default: docview-<form>.html in current dir)" )
394+
395+ duf := documentDocviewUploadCmd .Flags ()
396+ duf .StringVar (& docDocviewUploadFormCode , "form-code" , "" , "form code (fcd)" )
397+ duf .StringVar (& docDocviewUploadFormName , "form-name" , "" , "form name (wins over --form-code when both are given)" )
398+ duf .StringVar (& docDocviewUploadRouteCode , "route-code" , "" , "approval route code (required)" )
399+ duf .IntVar (& docDocviewUploadFromDocID , "from-docid" , 0 , "source document ID for a related document (0 = omit)" )
400+ duf .StringVar (& docDocviewUploadProxyUser , "proxy-user" , "" , "proxy applicant user code" )
401+ duf .StringVar (& docDocviewUploadDatas , "datas" , "" , "pre-fill data JSON: inline, file path, or - for stdin" )
402+ duf .StringVar (& docDocviewUploadFile , "file" , "" , "path to a file to pre-attach (at most one file)" )
403+ duf .StringVar (& docDocviewUploadFileName , "file-name" , "" , "override the attachment filename (default: basename of --file)" )
404+ duf .StringVar (& docDocviewUploadRemarks , "remarks" , "" , "attachment remarks (備考)" )
405+ duf .IntVar (& docDocviewUploadDetailNo , "detail-no" , 0 , "detail row number for an attachment-type form (0 = omit)" )
406+ duf .IntVar (& docDocviewUploadEvidenceType , "evidence-type" , - 1 , "電帳法書類区分 0:その他 / 1:電子取引 (-1 = omit; default 1 on server)" )
407+ duf .StringVarP (& docDocviewUploadOutput , "output" , "o" , "" , "output path: FILE, DIR/, or - for stdout (default: docview-<form>.html in current dir)" )
408+
409+ ovf := documentOpenviewCmd .Flags ()
410+ ovf .StringVar (& docOpenviewProxyUser , "proxy-user" , "" , "proxy user code (代理モードで書類を表示)" )
411+ ovf .StringVarP (& docOpenviewOutput , "output" , "o" , "" , "output path: FILE, DIR/, or - for stdout (default: openview-<docid>.html in current dir)" )
412+
413+ svf := documentStatusviewCmd .Flags ()
414+ svf .StringVarP (& docStatusviewOutput , "output" , "o" , "" , "output path: FILE, DIR/, or - for stdout (default: statusview-<docid>.html in current dir)" )
415+
305416 caf := documentCommentAddCmd .Flags ()
306417 caf .StringVar (& docCommentAddContent , "content" , "" , "comment content (required)" )
307418 caf .BoolVar (& docCommentAddAttention , "attention" , false , "mark as important comment (attentionflg=1)" )
@@ -560,6 +671,208 @@ func runDocumentDownload(cmd *cobra.Command, args []string) error {
560671 return nil
561672}
562673
674+ func runDocumentDocview (cmd * cobra.Command , args []string ) error {
675+ if docDocviewFormCode == "" && docDocviewFormName == "" {
676+ return fmt .Errorf ("either --form-code or --form-name is required" )
677+ }
678+ if ! cmd .Flags ().Changed ("route-code" ) {
679+ return fmt .Errorf ("--route-code is required (use an empty string \" \" for standard forms)" )
680+ }
681+ client , err := newClientFromFlags (cmd .Context ())
682+ if err != nil {
683+ return err
684+ }
685+ params := xpoint.DocviewParams {
686+ FormCode : docDocviewFormCode ,
687+ FormName : docDocviewFormName ,
688+ RouteCode : docDocviewRouteCode ,
689+ ProxyUser : docDocviewProxyUser ,
690+ }
691+ if docDocviewFromDocID != 0 {
692+ v := docDocviewFromDocID
693+ params .FromDocID = & v
694+ }
695+
696+ data , err := client .GetDocview (cmd .Context (), params )
697+ if err != nil {
698+ return err
699+ }
700+ defaultName := defaultDocviewFilename ("docview" , params .FormCode , params .FormName , 0 )
701+ return writeHTMLOutput (docDocviewOutput , defaultName , data )
702+ }
703+
704+ func runDocumentDocviewUpload (cmd * cobra.Command , args []string ) error {
705+ if docDocviewUploadFormCode == "" && docDocviewUploadFormName == "" {
706+ return fmt .Errorf ("either --form-code or --form-name is required" )
707+ }
708+ if ! cmd .Flags ().Changed ("route-code" ) {
709+ return fmt .Errorf ("--route-code is required (use an empty string \" \" for standard forms)" )
710+ }
711+ client , err := newClientFromFlags (cmd .Context ())
712+ if err != nil {
713+ return err
714+ }
715+
716+ params := xpoint.DocviewMultipartParams {
717+ FormCode : docDocviewUploadFormCode ,
718+ FormName : docDocviewUploadFormName ,
719+ RouteCode : docDocviewUploadRouteCode ,
720+ ProxyUser : docDocviewUploadProxyUser ,
721+ }
722+ if docDocviewUploadFromDocID != 0 {
723+ v := docDocviewUploadFromDocID
724+ params .FromDocID = & v
725+ }
726+ if docDocviewUploadDatas != "" {
727+ datas , err := loadStringInput (docDocviewUploadDatas )
728+ if err != nil {
729+ return fmt .Errorf ("load --datas: %w" , err )
730+ }
731+ params .Datas = datas
732+ }
733+ if docDocviewUploadFile != "" {
734+ content , err := os .ReadFile (docDocviewUploadFile )
735+ if err != nil {
736+ return fmt .Errorf ("read --file: %w" , err )
737+ }
738+ name := docDocviewUploadFileName
739+ if name == "" {
740+ name = filepath .Base (docDocviewUploadFile )
741+ }
742+ f := & xpoint.DocviewMultipartFile {
743+ Name : name ,
744+ Remarks : docDocviewUploadRemarks ,
745+ Content : content ,
746+ }
747+ if cmd .Flags ().Changed ("detail-no" ) {
748+ v := docDocviewUploadDetailNo
749+ f .DetailNo = & v
750+ }
751+ if docDocviewUploadEvidenceType >= 0 {
752+ v := docDocviewUploadEvidenceType
753+ f .EvidenceType = & v
754+ }
755+ params .File = f
756+ }
757+
758+ data , err := client .PostDocviewMultipart (cmd .Context (), params )
759+ if err != nil {
760+ return err
761+ }
762+ defaultName := defaultDocviewFilename ("docview" , params .FormCode , params .FormName , 0 )
763+ return writeHTMLOutput (docDocviewUploadOutput , defaultName , data )
764+ }
765+
766+ func runDocumentOpenview (cmd * cobra.Command , args []string ) error {
767+ docID , err := parseDocID (args [0 ])
768+ if err != nil {
769+ return err
770+ }
771+ client , err := newClientFromFlags (cmd .Context ())
772+ if err != nil {
773+ return err
774+ }
775+ data , err := client .GetDocumentOpenview (cmd .Context (), docID , docOpenviewProxyUser )
776+ if err != nil {
777+ return err
778+ }
779+ defaultName := defaultDocviewFilename ("openview" , "" , "" , docID )
780+ return writeHTMLOutput (docOpenviewOutput , defaultName , data )
781+ }
782+
783+ func runDocumentStatusview (cmd * cobra.Command , args []string ) error {
784+ docID , err := parseDocID (args [0 ])
785+ if err != nil {
786+ return err
787+ }
788+ client , err := newClientFromFlags (cmd .Context ())
789+ if err != nil {
790+ return err
791+ }
792+ data , err := client .GetDocumentStatusview (cmd .Context (), docID )
793+ if err != nil {
794+ return err
795+ }
796+ defaultName := defaultDocviewFilename ("statusview" , "" , "" , docID )
797+ return writeHTMLOutput (docStatusviewOutput , defaultName , data )
798+ }
799+
800+ // defaultDocviewFilename builds a reasonable default output filename for
801+ // docview/openview/statusview HTML responses.
802+ func defaultDocviewFilename (prefix , formCode , formName string , docID int ) string {
803+ switch {
804+ case docID > 0 :
805+ return fmt .Sprintf ("%s-%d.html" , prefix , docID )
806+ case formCode != "" :
807+ return fmt .Sprintf ("%s-%s.html" , prefix , sanitizeFilename (formCode ))
808+ case formName != "" :
809+ return fmt .Sprintf ("%s-%s.html" , prefix , sanitizeFilename (formName ))
810+ default :
811+ return prefix + ".html"
812+ }
813+ }
814+
815+ func sanitizeFilename (s string ) string {
816+ var b strings.Builder
817+ for _ , r := range s {
818+ switch r {
819+ case '/' , '\\' , ':' , '*' , '?' , '"' , '<' , '>' , '|' , '\x00' :
820+ b .WriteRune ('_' )
821+ default :
822+ b .WriteRune (r )
823+ }
824+ }
825+ return b .String ()
826+ }
827+
828+ // writeHTMLOutput writes HTML bytes to stdout (out == "-"), to a path given
829+ // by out (FILE or DIR/), or to defaultName in the current directory when out
830+ // is empty.
831+ func writeHTMLOutput (out , defaultName string , data []byte ) error {
832+ if out == "-" {
833+ _ , err := os .Stdout .Write (data )
834+ return err
835+ }
836+ var dst string
837+ switch {
838+ case out == "" :
839+ dst = defaultName
840+ case strings .HasSuffix (out , string (os .PathSeparator )) || strings .HasSuffix (out , "/" ):
841+ dst = filepath .Join (out , defaultName )
842+ default :
843+ if info , err := os .Stat (out ); err == nil && info .IsDir () {
844+ dst = filepath .Join (out , defaultName )
845+ } else {
846+ dst = out
847+ }
848+ }
849+ if err := os .WriteFile (dst , data , 0o600 ); err != nil {
850+ return fmt .Errorf ("write html: %w" , err )
851+ }
852+ fmt .Fprintf (os .Stderr , "saved: %s (%d bytes)\n " , dst , len (data ))
853+ return nil
854+ }
855+
856+ // loadStringInput accepts an inline string, a file path, or "-" for stdin
857+ // and returns the resulting string content.
858+ func loadStringInput (s string ) (string , error ) {
859+ if s == "-" {
860+ b , err := io .ReadAll (os .Stdin )
861+ if err != nil {
862+ return "" , fmt .Errorf ("read stdin: %w" , err )
863+ }
864+ return string (b ), nil
865+ }
866+ if info , err := os .Stat (s ); err == nil && ! info .IsDir () {
867+ b , err := os .ReadFile (s )
868+ if err != nil {
869+ return "" , fmt .Errorf ("read file: %w" , err )
870+ }
871+ return string (b ), nil
872+ }
873+ return s , nil
874+ }
875+
563876func runDocumentOpen (_ * cobra.Command , args []string ) error {
564877 docID , err := parseDocID (args [0 ])
565878 if err != nil {
0 commit comments