Add button to re-import Harvest cache time entry from API
This commit is contained in:
parent
a1c9199416
commit
f388f2d6cf
45
tailbone_harvest/templates/harvest/time-entries/view.mako
Normal file
45
tailbone_harvest/templates/harvest/time-entries/view.mako
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
## -*- coding: utf-8; -*-
|
||||||
|
<%inherit file="/master/view.mako" />
|
||||||
|
|
||||||
|
<%def name="object_helpers()">
|
||||||
|
${parent.object_helpers()}
|
||||||
|
${self.render_import_helper()}
|
||||||
|
</%def>
|
||||||
|
|
||||||
|
<%def name="render_import_helper()">
|
||||||
|
% if master.has_perm('import_from_harvest'):
|
||||||
|
<nav class="panel">
|
||||||
|
<p class="panel-heading">Re-Import</p>
|
||||||
|
<div class="panel-block buttons">
|
||||||
|
<div style="display: flex; flex-direction: column;">
|
||||||
|
% if master.has_perm('import_from_harvest'):
|
||||||
|
${h.form(master.get_action_url('import_from_harvest', instance), **{'@submit': 'importFromHarvestSubmitting = true'})}
|
||||||
|
${h.csrf_token(request)}
|
||||||
|
<b-button type="is-primary"
|
||||||
|
native-type="submit"
|
||||||
|
icon-pack="fas"
|
||||||
|
icon-left="redo"
|
||||||
|
:disabled="importFromHarvestSubmitting">
|
||||||
|
{{ importFromHarvestSubmitting ? "Working, please wait..." : "Re-Import from Harvest" }}
|
||||||
|
</b-button>
|
||||||
|
${h.end_form()}
|
||||||
|
% endif
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
% endif
|
||||||
|
</%def>
|
||||||
|
|
||||||
|
<%def name="modify_this_page_vars()">
|
||||||
|
${parent.modify_this_page_vars()}
|
||||||
|
% if master.has_perm('import_from_harvest'):
|
||||||
|
<script type="text/javascript">
|
||||||
|
|
||||||
|
ThisPageData.importFromHarvestSubmitting = false
|
||||||
|
|
||||||
|
</script>
|
||||||
|
% endif
|
||||||
|
</%def>
|
||||||
|
|
||||||
|
|
||||||
|
${parent.body()}
|
|
@ -62,7 +62,7 @@ class HarvestTimeEntryView(HarvestMasterView):
|
||||||
g.set_link('notes')
|
g.set_link('notes')
|
||||||
|
|
||||||
def configure_form(self, f):
|
def configure_form(self, f):
|
||||||
super(HarvestTimeEntryView, self).configure_form(f)
|
super().configure_form(f)
|
||||||
|
|
||||||
# make sure id is first field
|
# make sure id is first field
|
||||||
f.remove('id')
|
f.remove('id')
|
||||||
|
@ -84,11 +84,20 @@ class HarvestTimeEntryView(HarvestMasterView):
|
||||||
f.remove('task_id')
|
f.remove('task_id')
|
||||||
f.set_renderer('task', self.render_harvest_task)
|
f.set_renderer('task', self.render_harvest_task)
|
||||||
|
|
||||||
|
# hours
|
||||||
|
f.set_renderer('hours', self.render_hours)
|
||||||
|
|
||||||
f.set_type('notes', 'text')
|
f.set_type('notes', 'text')
|
||||||
|
|
||||||
f.set_type('billable_rate', 'currency')
|
f.set_type('billable_rate', 'currency')
|
||||||
f.set_type('cost_rate', 'currency')
|
f.set_type('cost_rate', 'currency')
|
||||||
|
|
||||||
|
def render_hours(self, entry, field):
|
||||||
|
hours = getattr(entry, field)
|
||||||
|
app = self.get_rattail_app()
|
||||||
|
duration = app.render_duration(hours=hours)
|
||||||
|
return f"{hours} ({duration})"
|
||||||
|
|
||||||
def get_xref_buttons(self, entry):
|
def get_xref_buttons(self, entry):
|
||||||
buttons = super(HarvestTimeEntryView, self).get_xref_buttons(entry)
|
buttons = super(HarvestTimeEntryView, self).get_xref_buttons(entry)
|
||||||
model = self.model
|
model = self.model
|
||||||
|
@ -105,6 +114,43 @@ class HarvestTimeEntryView(HarvestMasterView):
|
||||||
|
|
||||||
return buttons
|
return buttons
|
||||||
|
|
||||||
|
def import_from_harvest(self):
|
||||||
|
app = self.get_rattail_app()
|
||||||
|
handler = app.get_import_handler('to_rattail.from_harvest.import', require=True)
|
||||||
|
importer = handler.get_importer('HarvestTimeEntry')
|
||||||
|
importer.session = self.Session()
|
||||||
|
importer.setup()
|
||||||
|
|
||||||
|
cache_entry = self.get_instance()
|
||||||
|
if self.oneoff_import(importer, local_object=cache_entry):
|
||||||
|
self.request.session.flash(f"{self.get_model_title()} has been "
|
||||||
|
f"(re-)imported from Harvest: {cache_entry}")
|
||||||
|
else:
|
||||||
|
self.request.session.flash("Import failed!", 'error')
|
||||||
|
|
||||||
|
return self.redirect(self.get_action_url('view', cache_entry))
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def defaults(cls, config):
|
||||||
|
route_prefix = cls.get_route_prefix()
|
||||||
|
instance_url_prefix = cls.get_instance_url_prefix()
|
||||||
|
permission_prefix = cls.get_permission_prefix()
|
||||||
|
model_title = cls.get_model_title()
|
||||||
|
|
||||||
|
# normal defaults
|
||||||
|
cls._defaults(config)
|
||||||
|
|
||||||
|
# import from harvest
|
||||||
|
config.add_tailbone_permission(permission_prefix,
|
||||||
|
f'{permission_prefix}.import_from_harvest',
|
||||||
|
f"Re-Import {model_title} from Harvest")
|
||||||
|
config.add_route(f'{route_prefix}.import_from_harvest',
|
||||||
|
f'{instance_url_prefix}/import-from-harvest',
|
||||||
|
request_method='POST')
|
||||||
|
config.add_view(cls, attr='import_from_harvest',
|
||||||
|
route_name=f'{route_prefix}.import_from_harvest',
|
||||||
|
permission=f'{permission_prefix}.import_from_harvest')
|
||||||
|
|
||||||
|
|
||||||
def defaults(config, **kwargs):
|
def defaults(config, **kwargs):
|
||||||
base = globals()
|
base = globals()
|
||||||
|
|
Loading…
Reference in a new issue