Attachment field

I'm looking to create an ''attachment'' field in a module. Same thing as the field ''File Name'' in the ''Documents'' module.

How can I do that?

Thanks

Parents Reply Children
  • Kristjan,

    This will require more customization in order to retrieve the file name.  Typically, when a note record is created that contains a file attachment, a note record is saved and the attachment is stored on the file system with the Note ID in the ./upload directory.  Reviewing the code, it looks like when one of these attachments are downloaded, Sugar looks at the ./modules/Notes/NoteSoap.php file to determine the file name.

    This custom field that is created using the above method, does not create a note record, so a new customization will need to be added to tell Sugar how to retrieve the original file name.

    Other possible alternatives that you can use that are out of the box are to either:

    1. Use the existing Notes subpanel to attach files, or
    2. Using Module Builder, create a custom document type module and relate it to the module that you would like to attach files to.  This will ensure that attached files do not get lost in the note history (if you have a lot of note history on the record).

    Hope this helps,

    Lori

  • Hi Dan Kallish

                        I have used the similar procedure and was able to upload the file in Tasks module.

    But facing issue while deleting file 

    In console i have chekced and found this.


    jquery.min.js:4 DELETE http://<url>/rest/v10/Tasks/50cfb408-0856-11e6-a18a-fa163e8c8e90/file/attachment_c?delete_if_fails=true&platform=base 404 (Not Found)

    Tevfik Tümer David López

    Can you please update me regarding this.

    Regards

    Sidhu

  • Hi Vignesh V

                      It works thank you.

    Regard

    Sidhu

  • Hey,

    I'm facing same issue. How did you solve this problem?

  • Hi Juned Rawoot

    We stopped pursuing this further so we didn't get a solution, sorry.

    KGM

  • Hi Sidhu,

    Can you please tell me how did you solve this problem? I'm working in sugar 8.3. 

  • I Have done Whatever have In Blog When Finally click on quick repair 1st step is excuted succesfully field created and uploading documents succesfully.But in 2nd step we need to add delete attachment function where i got a parse error and stopping excution.

    Note:: Bold Text is the added code in original file 


    Parse error: syntax error, unexpected end of file, expecting function (T_FUNCTION) in D:\xampp1\htdocs\scrm\custom\modules\Cases\Case.php on line 359

    and this is the page Case.php

    <?php
    /*
    * Your installation or use of this SugarCRM file is subject to the applicable
    * terms available at
    * http://support.sugarcrm.com/Resources/Master_Subscription_Agreements/.
    * If you do not agree to all of the applicable terms or do not have the
    * authority to bind the entity as an authorized representative, then do not
    * install or use this SugarCRM file.
    *
    * Copyright (C) SugarCRM Inc. All rights reserved.
    */

    // aCase is used to store case information.

    require_once('include/upload_file.php');
    class aCase extends Basic
    {
    var $field_name_map = array();
    // Stored fields
    var $id;
    var $date_entered;
    var $date_modified;
    var $modified_user_id;
    var $assigned_user_id;
    var $team_id;
    var $case_number;
    var $resolution;
    var $description;
    var $name;
    var $status;
    var $priority;

    var $created_by;
    var $created_by_name;
    var $modified_by_name;

    // These are related
    var $bug_id;
    var $account_name;
    var $account_id;
    var $contact_id;
    var $task_id;
    var $note_id;
    var $meeting_id;
    var $call_id;
    var $email_id;
    var $assigned_user_name;
    var $team_name;
    var $system_id;

    var $table_name = "cases";
    var $rel_account_table = "accounts_cases";
    var $rel_contact_table = "contacts_cases";
    var $module_dir = 'Cases';
    var $object_name = "Case";
    var $importable = true;
    /** "%1" is the case_number, for emails
    * leave the %1 in if you customize this
    * YOU MUST LEAVE THE BRACKETS AS WELL*/
    var $emailSubjectMacro = '[CASE:%1]';

    // This is used to retrieve related fields from form posts.
    var $additional_column_fields = array(
    'bug_id',
    'assigned_user_name',
    'assigned_user_id',
    'contact_id',
    'task_id',
    'note_id',
    'meeting_id',
    'call_id',
    'email_id'
    );

    var $relationship_fields = array(
    'account_id'=>'accounts',
    'bug_id' => 'bugs',
    'task_id'=>'tasks',
    'note_id'=>'notes',
    'meeting_id'=>'meetings',
    'call_id'=>'calls',
    'email_id'=>'emails',
    );


    public function __construct()
    {
    parent::__construct();
    global $sugar_config;
    if (empty($sugar_config['require_accounts'])) {
    unset($this->required_fields['account_name']);
    }

    $this->setupCustomFields('Cases');
    foreach ($this->field_defs as $name => $field) {
    $this->field_name_map[$name] = $field;
    }
    }

    var $new_schema = true;

    function get_summary_text()
    {
    return "$this->name";
    }

    function listviewACLHelper()
    {
    $array_assign = parent::listviewACLHelper();
    $is_owner = false;
    if (!empty($this->account_id)) {
    if (!empty($this->account_id_owner)) {
    global $current_user;
    $is_owner = $current_user->id == $this->account_id_owner;
    }
    }
    if (!ACLController::moduleSupportsACL('Accounts') ||
    ACLController::checkAccess('Accounts', 'view', $is_owner)
    ) {
    $array_assign['ACCOUNT'] = 'a';
    } else {
    $array_assign['ACCOUNT'] = 'span';
    }

    return $array_assign;
    }

    /**
    * This function is a good location to save changes that have been made to a relationship.
    * This should be overridden in subclasses that have something to save.
    *
    * @param boolean $is_update true if this save is an update.
    * @param array $exclude a way to exclude relationships
    *
    * @see SugarBean::save_relationship_changes()
    */
    public function save_relationship_changes($is_update, $exclude = array())
    {
    parent::save_relationship_changes($is_update);

    if (!empty($this->contact_id)) {
    $this->set_case_contact_relationship($this->contact_id);
    }
    }

    function set_case_contact_relationship($contact_id)
    {
    global $app_list_strings;
    $default = $app_list_strings['case_relationship_type_default_key'];
    $this->load_relationship('contacts');
    $this->contacts->add($contact_id, array('contact_role'=>$default));
    }

    function fill_in_additional_detail_fields()
    {
    parent::fill_in_additional_detail_fields();

    if (!empty($this->id)) {
    $account_info = $this->getAccount($this->id);
    if (!empty($account_info)) {
    $this->account_name = $account_info['account_name'];
    $this->account_id = $account_info['account_id'];
    }
    }
    }

    function deleteAttachment($isduplicate="false"){

    if($this->ACLAccess('edit')){

    if($isduplicate=="true"){

    return true;

    }

    $removeFile = "upload://{$this->id}";

    }

    if(SugarAutoloader::fileExists($removeFile)) {

    if(!UploadFile::unlink($removeFile)) {

    $GLOBALS['log']->error("*** Could not unlink() file: [ {$removeFile} ]");

    }else{

    $this->filename = ";

    $this->file_mime_type = ";

    $this->file = ";

    $this->save();

    return true;

    }

    }else{

    $this->filename = ";

    $this->file_mime_type = ";

    $this->file = ";

    $this->save();

    return true;

    }

    return false;

    }


    /**
    * Returns a list of the associated contacts
    */
    function get_contacts()
    {
    $this->load_relationship('contacts');
    $query_array=$this->contacts->getQuery(true);

    // update the select clause in the returned query.
    $query_array['select'] = "SELECT contacts.id, contacts.first_name, contacts.last_name, contacts.title, contacts.email1, contacts.phone_work, contacts_cases.contact_role as case_role, contacts_cases.id as case_rel_id ";

    $query='';
    foreach ($query_array as $qstring) {
    $query.=' '.$qstring;
    }
    $temp = array('id', 'first_name', 'last_name', 'title', 'email1', 'phone_work', 'case_role', 'case_rel_id');
    return $this->build_related_list2($query, BeanFactory::getBean('Contacts'), $temp);
    }

    function get_list_view_data()
    {
    global $current_language;
    $app_list_strings = return_app_list_strings_language($current_language);

    $temp_array = $this->get_list_view_array();
    $temp_array['NAME'] = (($this->name == "") ? "<em>blank</em>" : $this->name);
    $temp_array['PRIORITY'] = empty($this->priority)? "" : (!isset($app_list_strings[$this->field_name_map['priority']['options']][$this->priority]) ? $this->priority : $app_list_strings[$this->field_name_map['priority']['options']][$this->priority]);
    $temp_array['STATUS'] = empty($this->status)? "" : (!isset($app_list_strings[$this->field_name_map['status']['options']][$this->status]) ? $this->status : $app_list_strings[$this->field_name_map['status']['options']][$this->status]);
    $temp_array['ENCODED_NAME'] = $this->name;
    $temp_array['CASE_NUMBER'] = $this->case_number;
    $temp_array['SET_COMPLETE'] = "<a href='index.php?return_module=Home&return_action=index&action=EditView&module=Cases&record=$this->id&status=Closed'>".SugarThemeRegistry::current()->getImage("close_inline", "title=".translate('LBL_LIST_CLOSE', 'Cases')." border='0'", null, null, '.gif', translate('LBL_LIST_CLOSE', 'Cases'))."</a>";
    $temp_array['CASE_NUMBER'] = format_number_display($this->case_number, $this->system_id);
    return $temp_array;
    }

    /**
    builds a generic search based on the query string using or
    do not include any $this-> because this is called on without having the class instantiated
    */
    function build_generic_where_clause($the_query_string)
    {
    $where_clauses = array();
    $the_query_string = $this->db->quote($the_query_string);
    array_push($where_clauses, "cases.name like '$the_query_string%'");
    array_push($where_clauses, "accounts.name like '$the_query_string%'");

    if (is_numeric($the_query_string)) {
    array_push($where_clauses, "cases.case_number like '$the_query_string%'");
    }

    $the_where = "";

    foreach ($where_clauses as $clause) {
    if ($the_where != "") {
    $the_where .= " or ";
    }
    $the_where .= $clause;
    }

    if ($the_where != "") {
    $the_where = "(".$the_where.")";
    }

    return $the_where;
    }

    function set_notification_body($xtpl, $case)
    {
    global $app_list_strings;

    $xtpl->assign("CASE_SUBJECT", $case->name);
    $xtpl->assign(
    "CASE_PRIORITY",
    (isset($case->priority) ? $app_list_strings['case_priority_dom'][$case->priority]:""));
    $xtpl->assign("CASE_STATUS", (isset($case->status) ? $app_list_strings['case_status_dom'][$case->status]:""));
    $xtpl->assign("CASE_DESCRIPTION", $case->description);

    return $xtpl;
    }

    function bean_implements($interface)
    {
    switch ($interface) {
    case 'ACL':
    return true;
    }
    return false;
    }

    function save($check_notify = false)
    {
    if (!isset($this->system_id) || empty($this->system_id)) {
    $admin = Administration::getSettings();
    $system_id = $admin->settings['system_system_id'];
    if (!isset($system_id)) {
    $system_id = 1;
    }
    $this->system_id = $system_id;
    }
    return parent::save($check_notify);
    }

    /**
    * retrieves the Subject line macro for InboundEmail parsing
    * @return string
    */
    function getEmailSubjectMacro()
    {
    global $sugar_config;
    return (isset($sugar_config['inbound_email_case_subject_macro']) && !empty($sugar_config['inbound_email_case_subject_macro'])) ?
    $sugar_config['inbound_email_case_subject_macro'] : $this->emailSubjectMacro;
    }

    function getAccount($case_id)
    {
    if (empty($case_id)) {
    return array();
    }
    $ret_array = array();
    $query = "SELECT acc.id, acc.name from accounts acc, cases where acc.id = cases.account_id and cases.id = '" . $case_id . "' and cases.deleted=0 and acc.deleted=0";
    $result = $this->db->query($query, true, " Error filling in additional detail fields: ");

    // Get the id and the name.
    $row = $this->db->fetchByAssoc($result);

    if ($row != null) {
    $ret_array['account_name'] = stripslashes($row['name']);
    $ret_array['account_id'] = $row['id'];
    } else {
    $ret_array['account_name'] = '';
    $ret_array['account_id'] = '';
    }
    return $ret_array;
    }
    }

  • Hi Ash,

    This looks like a syntax error in your custom file.

    Please make sure you use two single quotes ' ' below instead of just a one double quote ".

    $this->filename = ''; //denotes empty string (two single quotes)

    $this->file_mime_type = "; //same as above

    $this->file = "; //same as above

    Also use php -l custom/modules/Cases/Case.php to further resolve syntax errors if any.

    Regards.

    Hats