diff --git a/src/Apps/W1/Quality Management/app/src/Document/QltyInspection.Page.al b/src/Apps/W1/Quality Management/app/src/Document/QltyInspection.Page.al index 05b84cbb76..1ff25ae6b6 100644 --- a/src/Apps/W1/Quality Management/app/src/Document/QltyInspection.Page.al +++ b/src/Apps/W1/Quality Management/app/src/Document/QltyInspection.Page.al @@ -523,7 +523,7 @@ page 20406 "Qlty. Inspection" trigger OnAction() begin - Rec.TakeNewPicture(); + Rec.TakeNewMostRecentPicture(); end; } action(MoveToBin) diff --git a/src/Apps/W1/Quality Management/app/src/Document/QltyInspectionHeader.Table.al b/src/Apps/W1/Quality Management/app/src/Document/QltyInspectionHeader.Table.al index 8b095546e9..98e244eeed 100644 --- a/src/Apps/W1/Quality Management/app/src/Document/QltyInspectionHeader.Table.al +++ b/src/Apps/W1/Quality Management/app/src/Document/QltyInspectionHeader.Table.al @@ -23,6 +23,7 @@ using Microsoft.QualityManagement.Setup; using Microsoft.QualityManagement.Utilities; using Microsoft.QualityManagement.Workflow; using System.Device; +using System.IO; using System.Reflection; using System.Security.AccessControl; using System.Utilities; @@ -245,7 +246,7 @@ table 20405 "Qlty. Inspection Header" field(41; "Most Recent Picture"; Media) { Caption = 'Most Recent Picture'; - ToolTip = 'Specifies the most recent picture. Pictures can also be uploaded to document attachments and OneDrive automatically.'; + ToolTip = 'Specifies the most recent picture. Additionally, pictures can be uploaded to document attachments and OneDrive automatically.'; } field(45; "Existing Inspections This Rec."; Integer) { @@ -654,6 +655,8 @@ table 20405 "Qlty. Inspection Header" CannotFinishInspectionBecauseTheInspectionIsInResultErr: Label 'Cannot finish the inspection %1 because the inspection currently has the result %2, which is configured to disallow finishing.', Comment = '%1=the inspection, %2=the result code.'; MimeTypeTok: Label 'image/jpeg', Locked = true; AttachmentNameTok: Label '%1.%2', Locked = true, Comment = '%1=name,%2=extension'; + PictureFileFilterTok: Label 'Pictures |*.jpg;*.png;*.jpeg;*.bmp', Locked = true; + ImageTok: Label 'Image', Locked = true; PassFailQuantityInvalidErr: Label 'The %1 and %2 cannot exceed the %3. The %3 is currently exceeded by %4.', Comment = '%1=the passed quantity caption, %2=the failed quantity caption, %3=the source quantity caption, %4=the quantity exceeded'; local procedure UpdateMostRecentReinspection() @@ -1296,84 +1299,6 @@ table 20405 "Qlty. Inspection Header" QltyStartWorkflow.StartWorkflowInspectionReopens(Rec); end; - /// - /// This will use the camera to take a picture and add it to the inspection. - /// - /// - [TryFunction] - procedure TakeNewPicture() - var - Camera: Codeunit Camera; - PictureInStream: InStream; - Handled: Boolean; - PictureName: Text; - begin - TestStatusOpen(); - - QltyManagementSetup.Get(); - QltyManagementSetup.SanityCheckPictureAndCameraSettings(); - OnBeforeTakePicture(Rec, Handled); - if Handled then - exit; - - if not Camera.IsAvailable() then - Error(CameraNotAvailableErr); - - if not Camera.GetPicture(PictureInStream, PictureName) then - Error(UnableToSavePictureErr); - PictureName := StrSubstNo(PictureNameTok, Rec."No.", Rec."Re-inspection No.", CurrentDateTime()); - PictureName := DelChr(PictureName, '=', ' ><{}.@!`~''"|\/?&*():'); - - AddPicture(PictureInStream, PictureName, FileExtensionTok); - - OnAfterTakePicture(Rec); - end; - - /// - /// Adds the supplied instream to the inspection. - /// - /// - /// - /// - /// - [TryFunction] - internal procedure AddPicture(var PictureInStream: InStream; PictureName: Text; FileExtension: Text) - var - DocumentAttachment: Record "Document Attachment"; - - DocumentServiceManagement: Codeunit "Document Service Management"; - RecordRefToInspection: RecordRef; - FullFileNameWithExtension: Text; - Handled: Boolean; - begin - TestStatusOpen(); - - FullFileNameWithExtension := PictureName; - if not FullFileNameWithExtension.Contains('.') then - FullFileNameWithExtension := StrSubstNo(AttachmentNameTok, FullFileNameWithExtension, FileExtension); - - OnBeforeAddPicture(Rec, PictureInStream, PictureName, FileExtension, FullFileNameWithExtension, Handled); - if Handled then - exit; - - Clear(Rec."Most Recent Picture"); - Rec."Most Recent Picture".ImportStream(PictureInStream, PictureName, MimeTypeTok); - Rec.Modify(true); - - QltyManagementSetup.Get(); - if QltyManagementSetup."Additional Picture Handling" in [QltyManagementSetup."Additional Picture Handling"::"Save as attachment", QltyManagementSetup."Additional Picture Handling"::"Save as attachment and upload to OneDrive"] then begin - RecordRefToInspection.GetTable(Rec); - DocumentAttachment.SaveAttachmentFromStream(PictureInStream, RecordRefToInspection, FullFileNameWithExtension); - RecordRefToInspection.Modify(true); - end; - - if QltyManagementSetup."Additional Picture Handling" = QltyManagementSetup."Additional Picture Handling"::"Save as attachment and upload to OneDrive" then - if DocumentServiceManagement.IsConfigured() then - DocumentServiceManagement.ShareWithOneDrive(PictureName, FileExtension, PictureInStream); - - OnAfterAddPicture(Rec, PictureInStream, PictureName, FileExtension, FullFileNameWithExtension); - end; - /// /// Sets record filters based on the supplied variant and flags on whether it should be finding related inspections for the item, document, or something else. /// @@ -1659,6 +1584,105 @@ table 20405 "Qlty. Inspection Header" end; end; + #region Most Recent Picture Management + /// + /// This will use the camera to take a picture and add it to the Inspection document. + /// + /// + internal procedure TakeNewMostRecentPicture() + var + Camera: Codeunit Camera; + PictureInStream: InStream; + PictureName, FullFileNameWithExtension : Text; + begin + TestStatusOpen(); + + QltyManagementSetup.GetRecordOnce(); + QltyManagementSetup.SanityCheckPictureAndCameraSettings(); + + if not Camera.IsAvailable() then + Error(CameraNotAvailableErr); + + if not Camera.GetPicture(PictureInStream, PictureName) then + Error(UnableToSavePictureErr); + + PictureName := StrSubstNo(PictureNameTok, Rec."No.", Rec."Re-inspection No.", CurrentDateTime()); + PictureName := DelChr(PictureName, '=', ' ><{}.@!`~''"|\/?&*():'); + + FullFileNameWithExtension := PictureName; + if not FullFileNameWithExtension.Contains('.') then + FullFileNameWithExtension := StrSubstNo(AttachmentNameTok, FullFileNameWithExtension, FileExtensionTok); + + AddMostRecentPicture(PictureInStream, PictureName, MimeTypeTok); + ProcessAdditionalPictureHandling(PictureInStream, PictureName, FileExtensionTok, FullFileNameWithExtension); + end; + + internal procedure ImportMostRecentPicture() + var + FileManagement: Codeunit "File Management"; + QltyMiscHelpers: Codeunit "Qlty. Misc Helpers"; + PictureInStream: InStream; + PictureName, FileExtension, FullFileNameWithExtension : Text; + begin + TestStatusOpen(); + + if not QltyMiscHelpers.PromptAndImportIntoInStream(PictureFileFilterTok, PictureInStream, FullFileNameWithExtension) then + exit; + + if not FullFileNameWithExtension.Contains('.') then begin + PictureName := FileManagement.GetFileName(FullFileNameWithExtension); + FileExtension := FileExtensionTok; + FullFileNameWithExtension := StrSubstNo(AttachmentNameTok, FullFileNameWithExtension, FileExtensionTok); + end else begin + PictureName := FileManagement.GetFileName(FullFileNameWithExtension); + FileExtension := FileManagement.GetExtension(FullFileNameWithExtension); + end; + + AddMostRecentPicture(PictureInStream, ImageTok, ''); + ProcessAdditionalPictureHandling(PictureInStream, PictureName, FileExtension, FullFileNameWithExtension); + end; + + internal procedure DeleteMostRecentPicture() + begin + Clear(Rec."Most Recent Picture"); + Rec.Modify(true); + end; + + /// + /// Adds the supplied InStream to the Inspection document as "Most Recent Picture". + /// + /// + /// + /// + /// + local procedure AddMostRecentPicture(var PictureInStream: InStream; PictureName: Text; MimeType: Text) + begin + Clear(Rec."Most Recent Picture"); + if MimeType <> '' then + Rec."Most Recent Picture".ImportStream(PictureInStream, PictureName, MimeType) + else + Rec."Most Recent Picture".ImportStream(PictureInStream, PictureName); + Rec.Modify(); + end; + + local procedure ProcessAdditionalPictureHandling(var PictureInStream: InStream; PictureName: Text; FileExtension: Text; FullFileNameWithExtension: Text) + var + DocumentAttachment: Record "Document Attachment"; + DocumentServiceManagement: Codeunit "Document Service Management"; + RecordRefToQltyInspectionHeader: RecordRef; + begin + QltyManagementSetup.GetRecordOnce(); + if QltyManagementSetup."Additional Picture Handling" in [QltyManagementSetup."Additional Picture Handling"::"Save as attachment", QltyManagementSetup."Additional Picture Handling"::"Save as attachment and upload to OneDrive"] then begin + RecordRefToQltyInspectionHeader.GetTable(Rec); + DocumentAttachment.SaveAttachmentFromStream(PictureInStream, RecordRefToQltyInspectionHeader, FullFileNameWithExtension); + end; + + if QltyManagementSetup."Additional Picture Handling" = QltyManagementSetup."Additional Picture Handling"::"Save as attachment and upload to OneDrive" then + if DocumentServiceManagement.IsConfigured() then + DocumentServiceManagement.ShareWithOneDrive(PictureName, FileExtension, PictureInStream); + end; + #endregion Most Recent Picture Management + /// /// Use to supplement or replace default system behavior of finding related inspections. /// @@ -1726,54 +1750,6 @@ table 20405 "Qlty. Inspection Header" begin end; - /// - /// OnBeforeTakePicture occurs before a picture has been taken. - /// Use this to replace with your own picture taking dialog. - /// - /// var Record "Qlty. Inspection Header". - /// Set to true to replace the default behavior. - [IntegrationEvent(false, false)] - local procedure OnBeforeTakePicture(var QltyInspectionHeader: Record "Qlty. Inspection Header"; var Handled: Boolean) - begin - end; - - /// - /// OnAfterTakePicture occurs after a picture has been taken. - /// Picture storage will depend on the "Picture Upload Behavior" setting. - /// - /// var Record "Qlty. Inspection Header". - [IntegrationEvent(false, false)] - local procedure OnAfterTakePicture(var QltyInspectionHeader: Record "Qlty. Inspection Header") - begin - end; - - /// - /// OnBeforeAddPicture occurs before the supplied picture instream is added to the inspection. - /// - /// var Record "Qlty. Inspection Header" - /// var InStream - /// var Text - /// var Text - /// var Text - /// Set to true to replace the default behavior - [IntegrationEvent(false, false)] - local procedure OnBeforeAddPicture(var QltyInspectionHeader: Record "Qlty. Inspection Header"; var PictureInStream: InStream; var PictureName: Text; var FileExtension: Text; var FullFileNameWithExtension: Text; var Handled: Boolean) - begin - end; - - /// - /// OnAfterAddPicture occurs after the supplied picture instream is added to the inspection. - /// - /// var Record "Qlty. Inspection Header" - /// var InStream - /// var Text - /// var Text - /// var Text - [IntegrationEvent(false, false)] - local procedure OnAfterAddPicture(var QltyInspectionHeader: Record "Qlty. Inspection Header"; var PictureInStream: InStream; var PictureName: Text; var FileExtension: Text; var FullFileNameWithExtension: Text) - begin - end; - /// /// This is called when the Quality Inspection header is being updated automatically based on the inspection lines. /// Use this to inspect or adjust the result that the system automatically chose. diff --git a/src/Apps/W1/Quality Management/app/src/Document/QltyInspectionList.Page.al b/src/Apps/W1/Quality Management/app/src/Document/QltyInspectionList.Page.al index 7a3242e013..37d125ec3c 100644 --- a/src/Apps/W1/Quality Management/app/src/Document/QltyInspectionList.Page.al +++ b/src/Apps/W1/Quality Management/app/src/Document/QltyInspectionList.Page.al @@ -225,7 +225,7 @@ page 20408 "Qlty. Inspection List" trigger OnAction() begin - Rec.TakeNewPicture(); + Rec.TakeNewMostRecentPicture(); end; } action(ChangeStatusFinish) diff --git a/src/Apps/W1/Quality Management/app/src/Document/QltyMostRecentPicture.Page.al b/src/Apps/W1/Quality Management/app/src/Document/QltyMostRecentPicture.Page.al index 8e1a0cf75f..cea4571a75 100644 --- a/src/Apps/W1/Quality Management/app/src/Document/QltyMostRecentPicture.Page.al +++ b/src/Apps/W1/Quality Management/app/src/Document/QltyMostRecentPicture.Page.al @@ -4,12 +4,11 @@ // ------------------------------------------------------------------------------------------------ namespace Microsoft.QualityManagement.Document; -using Microsoft.QualityManagement.Utilities; using System.Device; page 20431 "Qlty. Most Recent Picture" { - Caption = 'Quality Most Recent Picture'; + Caption = 'Most Recent Picture'; DeleteAllowed = false; InsertAllowed = false; LinksAllowed = false; @@ -35,35 +34,28 @@ page 20431 "Qlty. Most Recent Picture" action(TakePicture) { Caption = 'Take'; + Visible = IsCameraAvailable; Image = Camera; - ToolTip = 'Activate the camera on the device.'; - Visible = IsCameraAvailable and (not HideActions); + ToolTip = 'Take a picture using the camera on the device.'; trigger OnAction() begin - Rec.TakeNewPicture(); + Rec.TakeNewMostRecentPicture(); end; } action(ImportPicture) { Caption = 'Import'; Image = Import; - ToolTip = 'Import a picture file.'; - Visible = not HideActions; + ToolTip = 'Import a picture from existing file.'; trigger OnAction() - var - QltyMiscHelpers: Codeunit "Qlty. Misc Helpers"; - InStream: InStream; begin if Rec."Most Recent Picture".HasValue() then if not Confirm(OverrideImageQst) then exit; - Clear(Rec."Most Recent Picture"); - if QltyMiscHelpers.PromptAndImportIntoInStream(FileFilterTok, InStream) then begin - Rec."Most Recent Picture".ImportStream(InStream, ImageTok); - Rec.Modify(); - end; + + Rec.ImportMostRecentPicture(); end; } action(DeletePicture) @@ -71,52 +63,40 @@ page 20431 "Qlty. Most Recent Picture" Caption = 'Delete'; Enabled = DeleteExportEnabled; Image = Delete; - ToolTip = 'Delete the record.'; - Visible = not HideActions; + ToolTip = 'Delete the most recent picture.'; trigger OnAction() begin - DeleteMostRecentPicture(); + if GuiAllowed() then + if not Confirm(DeleteImageQst) then + exit; + + Rec.DeleteMostRecentPicture(); end; } } } var - Camera: Codeunit Camera; IsCameraAvailable: Boolean; DeleteExportEnabled: Boolean; - HideActions: Boolean; DeleteImageQst: Label 'Are you sure you want to delete the picture?'; OverrideImageQst: Label 'The existing picture will be replaced. Do you want to continue?'; - FileFilterTok: Label 'Pictures |*.jpg;*.png;*.jpeg;*.bmp', Locked = true; - ImageTok: Label 'Image', Locked = true; - - trigger OnAfterGetCurrRecord() - begin - SetEditableOnPictureActions(); - end; trigger OnOpenPage() + var + Camera: Codeunit Camera; begin IsCameraAvailable := Camera.IsAvailable(); end; - local procedure SetEditableOnPictureActions() + trigger OnAfterGetCurrRecord() begin - DeleteExportEnabled := Rec."Most Recent Picture".HasValue(); + SetEditableOnPictureActions(); end; - /// - /// Deletes the most recent picture. - /// - procedure DeleteMostRecentPicture() + local procedure SetEditableOnPictureActions() begin - if GuiAllowed() then - if not Confirm(DeleteImageQst) then - exit; - - Clear(Rec."Most Recent Picture"); - Rec.Modify(true); + DeleteExportEnabled := Rec."Most Recent Picture".HasValue(); end; } diff --git a/src/Apps/W1/Quality Management/app/src/Utilities/QltyMiscHelpers.Codeunit.al b/src/Apps/W1/Quality Management/app/src/Utilities/QltyMiscHelpers.Codeunit.al index e114b140cf..ed129e17b4 100644 --- a/src/Apps/W1/Quality Management/app/src/Utilities/QltyMiscHelpers.Codeunit.al +++ b/src/Apps/W1/Quality Management/app/src/Utilities/QltyMiscHelpers.Codeunit.al @@ -26,7 +26,7 @@ codeunit 20599 "Qlty. Misc Helpers" TranslatableNoLbl: Label 'No'; LockedYesLbl: Label 'Yes', Locked = true; LockedNoLbl: Label 'No', Locked = true; - ImportFromLbl: Label 'Import From File'; + ImportFromLbl: Label 'Import from File'; DateKeywordTxt: Label 'Date'; YesNoKeyword1Txt: Label 'Does the'; YesNoKeyword2Txt: Label 'Do the'; @@ -101,11 +101,9 @@ codeunit 20599 "Qlty. Misc Helpers" /// File type filter for the upload dialog (e.g., "*.xml|*.txt") /// Output: InStream containing the uploaded file contents /// True if file was successfully selected and uploaded; False if user cancelled or upload failed - internal procedure PromptAndImportIntoInStream(FilterString: Text; var InStream: InStream) Worked: Boolean - var - ServerFile: Text; + internal procedure PromptAndImportIntoInStream(FilterString: Text; var InStream: InStream; var ServerFileName: Text) Worked: Boolean begin - Worked := UploadIntoStream(ImportFromLbl, '', FilterString, ServerFile, InStream); + Worked := UploadIntoStream(ImportFromLbl, '', FilterString, ServerFileName, InStream); end; ///