-
-
Notifications
You must be signed in to change notification settings - Fork 2.4k
Customer tags #3118
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Customer tags #3118
Conversation
…include data row for Tags
… import functions to allow tags in import file , created customer import csv helper and added Tag input on Customer creation/editing form
… migrations for Tags module
… customer CSV import
jekkos
left a comment
There was a problem hiding this 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 | ||
| // { |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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); |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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 ?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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'], |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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.
- 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.
- 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."); |
There was a problem hiding this comment.
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); |
There was a problem hiding this comment.
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)) |
There was a problem hiding this comment.
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) |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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; | ||
|
|
||
|
|
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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?
I haven't looked at the code yet, but a couple of thoughts on design. All of these thoughts are IMO:
|
objecttothis
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
application/config/autoload.php
Outdated
| 'Tax_code', | ||
| 'Tax_jurisdiction' | ||
| 'Tax_jurisdiction', | ||
| 'Tag' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or person_attribute
There was a problem hiding this comment.
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) |
There was a problem hiding this comment.
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() | ||
| { | ||
|
|
There was a problem hiding this comment.
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; | ||
|
|
||
|
|
There was a problem hiding this comment.
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) |
There was a problem hiding this comment.
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.
|
Yeah that's fine. I don't have a hangup on person_tags, but person_attributes is fin with me too. We may not even need to refactor attributes to item_attributes if we go with person_attributes.
Get Outlook for Android<https://aka.ms/ghei36>
________________________________
From: jekkos <[email protected]>
Sent: Wednesday, March 3, 2021 12:08:49 PM
To: opensourcepos/opensourcepos <[email protected]>
Cc: objecttothis <[email protected]>; Mention <[email protected]>
Subject: Re: [opensourcepos/opensourcepos] Customer tags (#3118)
@jekkos commented on this pull request.
________________________________
In application/controllers/Customers.php<#3118 (comment)>:
/*
Customers import from csv spreadsheet
*/
public function csv()
{
$name = 'import_customers.csv';
- $data = file_get_contents('../' . $name);
- force_download($name, $data);
+ $allowed_tags = $this->Tag->get_definition_names(FALSE);
@objecttothis<https://github.com/objecttothis> are you fine to make it person_attributes as @daN4cat<https://github.com/daN4cat> ? Let's make sure we're on the same page here then.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub<#3118 (comment)>, or unsubscribe<https://github.com/notifications/unsubscribe-auth/AEI2X243ZFU2UKM3T7FJQ3TTBXVBDANCNFSM4YJ3XYLQ>.
|
|
|
||
| $consent = $data[3] == '' ? 0 : 1; | ||
| //check for consent in file upload, y == yes , empty field == no | ||
| $consent = $line['Consent'] == '' ? 0 : 1; |
There was a problem hiding this comment.
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() |
There was a problem hiding this comment.
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.
…moved it from employees, customers and suppliers forms
…include data row for Tags
… import functions to allow tags in import file , created customer import csv helper and added Tag input on Customer creation/editing form
… migrations for Tags module
… customer CSV import
…moved it from employees, customers and suppliers forms
739941b to
091e294
Compare
|
@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. |
@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 :