Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@DamianoSilverhand
Copy link

@jekkos this pull request adds Customer custom fields, hereby named as Tags, with the same functionality as Item Attributes. But as of issue #3111, works needs to be done on pulling the tags from the database and displaying them in the customer view.
Major changes include :

  1. New Migration to include new Tags module
  2. Customer CSV import and file generation refactored to include Tags.

Copy link
Member

@jekkos jekkos left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changeset looks good overall, I'll do a more thorough review a bit later on. We'll have to merge the work from @objecttothis first to have the import improvements. Once that is done we can polish this one up a bit and reuse some common logic (like the import validation checks).

Thanks already for the work done here.

// }
// }
// else
// {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this new code or old code commented out?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess this is unused so it can be removed?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jekkos yes the commented code is the original code involved with csv import and is unused in this PR.

$name = 'import_customers.csv';
$data = file_get_contents('../' . $name);
force_download($name, $data);
$allowed_tags = $this->Tag->get_definition_names(FALSE);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the naming maybe even better then 'attributes'. However currently it's not really clear that attributes are linked to items and tags to customers from the naming only.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jekkos which naming should be implemented, should I keep the tags as they are or change to customer_tags or customer_attributes as suggested by @objecttothis ?

Copy link
Member

@objecttothis objecttothis Mar 1, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I need to clarify, since my position changed below after reading some of @jekkos comments. My recommendation is to change it to person_tags:

  • The naming scales well to use this in suppliers and employees.
  • It's shorter than person_attributes or customer_attributes.
  • We can later refactor attributes to be item_tags instead of attributes.
  • The GUI everywhere should be just tags since the context will make it clear about which tags we are talking about... although we will need to think through how we want to define tags. Once it gets scaled to employees and suppliers then just probably have a multi-select dropdown allowing you to choose which types of "person" the tag will apply to.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@objecttothis are you fine to make it person_attributes as @daN4cat ? Let's make sure we're on the same page here then.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I'm concerned about tags being a semantic set / grouping concept.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok person_attributes it is.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will start working on the recommended changes, meaning I will have to create a new branch person_attributes for my next PR

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@objecttothis are you fine to make it person_attributes as @daN4cat ? Let's make sure we're on the same page here then.

No complaint here. Sorry for not being able to respond earlier.

'zip' => $data[10],
'country' => $data[11],
'comments' => $data[12]
'phone_number' => $line['Phone Number'],
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok good to use the key names to identify the fields here

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, in fact it's better to refactor the rest so all of them are using the key names. This provides a few advantages.

  1. If the user moves columns around in their CSV it will still process them properly (as long as they don't change the names of columns.
  2. It's easier to read in the code.

$failCodes[] = $i;
$failed_row = $i+1;
$failCodes[] = $failed_row;
log_message("ERROR","CSV Item import failed on line ". $failed_row .". This customer was not imported.");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess we show a popup as well in the end? Should be customer import not item


if(count($failCodes) > 0)
{
$message = $this->lang->line('customers_csv_import_partially_failed') . ' (' . count($failCodes) . '): ' . implode(', ', $failCodes);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea to do the rollback in case a failure occurs

$dropdown_values = $this->Tag->get_definition_values($tag_data['definition_id']);
$dropdown_values[] = '';

if(in_array($tag_value, $dropdown_values) === FALSE && !empty($tag_value))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure if this code can be extracted / reused (as we might have similar checks now in the item import). Maybe @objecttothis after we'll merge your PR?

* @param object $file_handle File handle to check
* @return bool Returns TRUE if the BOM exists and FALSE otherwise.
*/
function customer_bom_exists(&$file_handle)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This helper can probably be shared between item and customer import. I gues the latter will be merged first

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. Reduces code duplication. The item import changes need to be imported before this PR.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok we can leave this open for now, will need to be resolved once @objecttothis changes are in.

UNIQUE `tag_links_uq1` (`tag_id`, `definition_id`, `person_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;


Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

from a db point of view I suppose it's more simple to do it this way.. I would rename the module to sth like Customer Tags and then Attributes can be named 'Item tags' just for consistency

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jekkos I'm fine with changing attributes to tags, which would make the variable names more brief, but I would advocate that this change be implemented on the People level so that tags could later be applied to Suppliers and Employees, even if this PR only implements them for customers ATM. I think the naming then could be people_tags and then we have a technical debt for someone to refactor attributes to item_tags. Thoughts?

Copy link
Member

@jekkos jekkos Mar 1, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we use the person table to link the tags to then it's just a matter of running the queries in those controllers as well. I think that for this change that's enough.. Link it to the person table and then have it functional in the customer module only. If you get the database model right, you'll be able to rework and factor out the common code to use it in employees and suppliers as well?

@objecttothis
Copy link
Member

@jekkos this pull request adds Customer custom fields, hereby named as Tags, with the same functionality as Item Attributes. But as of issue #3111, works needs to be done on pulling the tags from the database and displaying them in the customer view.
Major changes include :

1. New Migration to include new Tags module

2. Customer CSV import and file generation refactored to include Tags.

I haven't looked at the code yet, but a couple of thoughts on design. All of these thoughts are IMO:

  • This needs to be implemented at the person level, not just the customer level. The reason is that you want to be able to add attributes to the Suppliers, Customers and Employees. All of those are at the People level. It's OK if we only do customers for now, but this needs to be designed in such a way as to allow the easy expansion to Suppliers and Employees.
  • The database needs to use a separate set of definition, attribute and link tables from item attributes.
  • I think we need to avoid overcomplication of naming conventions and just stick to "Item Attributes" and "People Attributes". On the UI, they can just be called attributes and then the business logic needs to differentiate depending on whether we are working with people or items.

Copy link
Member

@objecttothis objecttothis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For clarity, my comments are all IMO and open for discussion on them. @jekkos and @daN4cat feel free to override them. I feel strongly about the naming conventions, but then again, I feel strongly about most things ;)

'Tax_code',
'Tax_jurisdiction'
'Tax_jurisdiction',
'Tag'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should stick with the current naming and call this person_attribute instead of tag IMO. @jekkos @daN4cat thoughts?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes or person_tags in this case? I must say that I like the fact that it's shorter, especially if we have to identify to which module it belongs?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tags tend to be used to create semantic sets, we risk of mixing up terminology.
What about leaving attribute?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or person_attribute

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also fine, I mostly prefer shorter naming, but might be less correct as @daN4cat says here.

* @param object $file_handle File handle to check
* @return bool Returns TRUE if the BOM exists and FALSE otherwise.
*/
function customer_bom_exists(&$file_handle)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. Reduces code duplication. The item import changes need to be imported before this PR.


public function down()
{

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This down function needs to be completed... I'm guessing it would just be a script that deletes these tables.

UNIQUE `tag_links_uq1` (`tag_id`, `definition_id`, `person_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci;


Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jekkos I'm fine with changing attributes to tags, which would make the variable names more brief, but I would advocate that this change be implemented on the People level so that tags could later be applied to Suppliers and Employees, even if this PR only implements them for customers ATM. I think the naming then could be people_tags and then we have a technical debt for someone to refactor attributes to item_tags. Thoughts?

echo form_hidden("tag_ids[$definition_id]", $definition_value['tag_id']);
$tag_value = $definition_value['tag_value'];

if ($definition_value['definition_type'] == DATE)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO these need to be in a switch statement rather than a bunch of else if statements... if not, we need to at minimum modify this to use the === operator.

@objecttothis
Copy link
Member

objecttothis commented Mar 3, 2021 via email


$consent = $data[3] == '' ? 0 : 1;
//check for consent in file upload, y == yes , empty field == no
$consent = $line['Consent'] == '' ? 0 : 1;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This functionality wasn't in there before so if you don't want to include it then that's fine, but you might take a look at how I've handled true/false/0/1/NULL columns in item imports from #3029. I'm not sure, but current implementation here won't be able to handle true/false/TRUE/FALSE/NULL, but instead translating them all to 1.

force_download($name, $data, TRUE);
}

public function csv_import()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

with #3029 I have a function in the importfile_helper called get_csv_file(). You'll want to use that here to take advantage of code_reuse, and that I've done extensive speed optimizations on that function to reduce time it takes to injest large files. It's not as good of a system as an injest queue would be, but we don't currently have that in the code.

@DamianoSilverhand
Copy link
Author

@jekkos @objecttothis @daN4cat I am kindly requesting that this PR be closed in favor of #3161 , branch person attributes, with reworked changes and additions and extension of person attributes to Suppliers and Employees.

@DamianoSilverhand DamianoSilverhand deleted the customer_tags branch April 16, 2021 10:40
jekkos added a commit that referenced this pull request Jun 7, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants