From fb692c5f36d073818aec001f281a70a77dfb6977 Mon Sep 17 00:00:00 2001 From: Moritz Bunkus Date: Tue, 9 Jul 2013 11:59:11 +0200 Subject: [PATCH] Pflichtenheft-Angebot/Auftrag: Liste in Tab anzeigen --- SL/Controller/RequirementSpecOrder.pm | 61 +++++++++++++++ SL/DB/RequirementSpec.pm | 12 +++ js/locale/de.js | 5 ++ js/requirement_spec.js | 43 +++++++++++ locale/de/all | 18 ++++- templates/webpages/requirement_spec/show.html | 1 + .../webpages/requirement_spec_order/list.html | 77 +++++++++++++++++++ 7 files changed, 216 insertions(+), 1 deletion(-) create mode 100644 SL/Controller/RequirementSpecOrder.pm create mode 100644 templates/webpages/requirement_spec_order/list.html diff --git a/SL/Controller/RequirementSpecOrder.pm b/SL/Controller/RequirementSpecOrder.pm new file mode 100644 index 000000000..67b780f42 --- /dev/null +++ b/SL/Controller/RequirementSpecOrder.pm @@ -0,0 +1,61 @@ +package SL::Controller::RequirementSpecOrder; + +use strict; +use utf8; + +use parent qw(SL::Controller::Base); + +use SL::ClientJS; +use SL::DB::RequirementSpec; +use SL::DB::RequirementSpecOrder; +use SL::Helper::Flash; +use SL::Locale::String; + +use Rose::Object::MakeMethods::Generic +( + 'scalar --get_set_init' => [ qw(requirement_spec js) ], +); + +__PACKAGE__->run_before('setup'); + +# +# actions +# + + +sub action_list { + my ($self) = @_; + + $::lxdebug->dump(0, "hmm", $self->requirement_spec->sections_sorted); + $self->render('requirement_spec_order/list', { layout => 0 }); +} + +# +# filters +# + +sub setup { + my ($self) = @_; + + $::auth->assert('sales_quotation_edit'); + $::request->{layout}->use_stylesheet("${_}.css") for qw(jquery.contextMenu requirement_spec); + $::request->{layout}->use_javascript("${_}.js") for qw(jquery.jstree jquery/jquery.contextMenu client_js requirement_spec); + + return 1; +} + +sub init_requirement_spec { + my ($self) = @_; + $self->requirement_spec(SL::DB::RequirementSpec->new(id => $::form->{requirement_spec_id})->load) if $::form->{requirement_spec_id}; +} + +sub init_js { + my ($self) = @_; + $self->js(SL::ClientJS->new); +} + +# +# helpers +# + +1; diff --git a/SL/DB/RequirementSpec.pm b/SL/DB/RequirementSpec.pm index cd1c837f6..72651a3c3 100644 --- a/SL/DB/RequirementSpec.pm +++ b/SL/DB/RequirementSpec.pm @@ -27,6 +27,11 @@ __PACKAGE__->meta->add_relationship( class => 'SL::DB::RequirementSpec', column_map => { id => 'working_copy_id' }, }, + orders => { + type => 'one to many', + class => 'SL::DB::RequirementSpecOrder', + column_map => { id => 'requirement_spec_id' }, + }, ); __PACKAGE__->meta->initialize; @@ -71,6 +76,13 @@ sub sections_sorted { sub sections { §ions_sorted; } +sub orders_sorted { + my ($self, %params) = _hashify(1, @_); + my $by = $params{by} || 'itime'; + + return [ sort { $a->$by cmp $b->$by } @{ $self->orders } ]; +} + sub displayable_name { my ($self) = @_; diff --git a/js/locale/de.js b/js/locale/de.js index c38b79333..6e2aa8e08 100644 --- a/js/locale/de.js +++ b/js/locale/de.js @@ -9,9 +9,11 @@ namespace("kivi").setupLocale({ "Copy requirement spec":"Pflichtenheft kopieren", "Copy template":"Vorlage kopieren", "Create PDF":"PDF erzeugen", +"Create new qutoation/order":"", "Create new version":"Neue Version anlegen", "Database Connection Test":"Test der Datenbankverbindung", "Delete":"Löschen", +"Delete quotation/order":"", "Delete requirement spec":"Pflichtenheft löschen", "Delete template":"Vorlage löschen", "Delete text block":"Textblock löschen", @@ -19,10 +21,12 @@ namespace("kivi").setupLocale({ "Do you really want to revert to this version?":"Wollen Sie wirklich auf diese Version zurücksetzen?", "Do you want to set the account number \"#1\" to \"#2\" and the name \"#3\" to \"#4\"?":"Soll die Kontonummer \"#1\" zu \"#2\" und den Name \"#3\" zu \"#4\" geändert werden?", "Edit":"Bearbeiten", +"Edit article/section assignments":"", "Edit text block":"Textblock bearbeiten", "Enter longdescription":"Langtext eingeben", "Function block actions":"Funktionsblockaktionen", "Map":"Karte", +"Orders/Quotations actions":"", "Part picker":"Artikelauswahl", "Paste":"Einfügen", "Paste template":"Vorlage einfügen", @@ -39,5 +43,6 @@ namespace("kivi").setupLocale({ "The selected database is still configured for client \"#1\". If you delete the database that client will stop working until you re-configure it. Do you still want to delete the database?":"Die auswählte Datenbank ist noch für Mandant \"#1\" konfiguriert. Wenn Sie die Datenbank löschen, wird der Mandanten nicht mehr funktionieren, bis er anders konfiguriert wurde. Wollen Sie die Datenbank trotzdem löschen?", "Time/cost estimate actions":"Aktionen für Kosten-/Zeitabschätzung", "Toggle marker":"Markierung umschalten", +"Update quotation/order":"", "Version actions":"Aktionen für Versionen" }); diff --git a/js/requirement_spec.js b/js/requirement_spec.js index effcf3d86..9b68bc7b6 100644 --- a/js/requirement_spec.js +++ b/js/requirement_spec.js @@ -317,6 +317,36 @@ ns.standard_time_cost_estimate_ajax_call = function(key, opt) { return true; }; +// ------------------------------------------------------------------------- +// --------------------------- quotations/orders --------------------------- +// ------------------------------------------------------------------------- + +ns.find_quotation_order_id = function(clicked_elt) { + return $(clicked_elt).find('>[name=order_id]').val(); +}; + +ns.standard_quotation_order_ajax_call = function(key, opt, other_data) { + var data = { + action: "RequirementSpecOrder/" + key, + requirement_spec_id: $('#requirement_spec_id').val(), + id: ns.find_quotation_order_id(opt.$trigger) + }; + + // console.log("I would normally POST the following now:"); + // console.log(data); + $.post("controller.pl", $.extend(data, other_data || {}), kivi.eval_json_result); + + return true; +}; + +ns.disable_edit_quotation_order_commands = function(key, opt) { + return ns.find_quotation_order_id(opt.$trigger) == undefined; +}; + +ns.disable_create_quotation_order_commands = function(key, opt) { + return !$('#quotations_and_orders_sections'); +}; + // ------------------------------------------------------------------------- // ---------------------------- general actions ---------------------------- // ------------------------------------------------------------------------- @@ -474,6 +504,19 @@ ns.create_context_menus = function(is_template) { }, general_actions) }); + $.contextMenu({ + selector: '.quotations-and-orders-context-menu,.quotations-and-orders-order-context-menu', + items: $.extend({ + heading: { name: kivi.t8('Orders/Quotations actions'), className: 'context-menu-heading' } + , edit: { name: kivi.t8('Edit article/section assignments'), icon: "edit", callback: ns.standard_quotation_order_ajax_call } + , sep1: "---------" + , new: { name: kivi.t8('Create new qutoation/order'), icon: "add", callback: ns.standard_quotation_order_ajax_call, disabled: ns.disable_create_quotation_order_commands} + , update: { name: kivi.t8('Update quotation/order'), icon: "update", callback: ns.standard_quotation_order_ajax_call, disabled: ns.disable_edit_quotation_order_commands } + , sep2: "---------" + , delete: { name: kivi.t8('Delete quotation/order'), icon: "delete", callback: ns.ask_delete_quotation_order, disabled: ns.disable_edit_quotation_order_commands } + }, general_actions) + }); + $.contextMenu({ selector: '#content', items: general_actions diff --git a/locale/de/all b/locale/de/all index a6ea88c87..b6528d7bb 100755 --- a/locale/de/all +++ b/locale/de/all @@ -243,6 +243,7 @@ $self->{texts} = { 'Are you sure you want to remove the marked entries from the queue?' => 'Sind Sie sicher, dass die markierten Einträge von der Warteschlange gelöscht werden sollen?', 'Are you sure you want to update the prices' => 'Sind Sie sicher, dass Sie die Preise aktualisieren wollen?', 'Are you sure?' => 'Sind Sie sicher?', + 'Article' => '', 'Article Code' => 'Artikelkürzel', 'Article Code missing!' => 'Artikelkürzel fehlt', 'Article type (see below)' => 'Artikeltyp (siehe unten)', @@ -254,6 +255,7 @@ $self->{texts} = { 'Assembly Number missing!' => 'Erzeugnisnummer fehlt!', 'Asset' => 'Aktiva/Mittelverwendung', 'Assets' => 'Aktiva', + 'Assignment of articles to sections' => '', 'Assistant for general ledger corrections' => 'Assistent für die Korrektur von Hauptbucheinträgen', 'Assume Tax Consultant Data in Tax Computation?' => 'Beraterdaten in UStVA übernehmen?', 'At least' => 'Mindestens', @@ -588,6 +590,7 @@ $self->{texts} = { 'Create new department' => 'Neue Abteilung erfassen', 'Create new payment term' => 'Neue Zahlungsbedingung anlegen', 'Create new project type' => 'Neuen Projekttypen anlegen', + 'Create new qutoation/order' => '', 'Create new templates from master templates' => 'Neue Druckvorlagen aus Vorlagensatz erstellen', 'Create new version' => 'Neue Version anlegen', 'Create one from the context menu by right-clicking on this text.' => 'Erstellen Sie einen aus dem Kontextmenü, indem Sie auf diesen Text rechtsklicken.', @@ -716,7 +719,7 @@ $self->{texts} = { 'Default client' => 'Standardmandant', 'Default currency' => 'Standardwährung', 'Default currency missing!' => 'Standardwährung fehlt!', - 'Default hourly rate for new customers' => '', + 'Default hourly rate for new customers' => 'Standard-Stundensatz für neue Kunden', 'Default output medium' => 'Standardausgabekanal', 'Default printer' => 'Standarddrucker', 'Default template format' => 'Standardvorlagenformat', @@ -730,6 +733,7 @@ $self->{texts} = { 'Delete drafts' => 'Entwürfe löschen', 'Delete links' => 'Verknüpfungen löschen', 'Delete profile' => 'Profil löschen', + 'Delete quotation/order' => '', 'Delete requirement spec' => 'Pflichtenheft löschen', 'Delete template' => 'Vorlage löschen', 'Delete text block' => 'Textblock löschen', @@ -895,6 +899,7 @@ $self->{texts} = { 'Edit Vendor Invoice' => 'Einkaufsrechnung bearbeiten', 'Edit Warehouse' => 'Lager bearbeiten', 'Edit acceptance status' => 'Abnahmestatus bearbeiten', + 'Edit article/section assignments' => '', 'Edit background job' => 'Hintergrund-Job bearbeiten', 'Edit bank account' => 'Bankkonto bearbeiten', 'Edit business' => 'Kunden-/Lieferantentyp bearbeiten', @@ -1481,6 +1486,7 @@ $self->{texts} = { 'No printers have been created yet.' => 'Es wurden noch keine Drucker angelegt.', 'No problems were recognized.' => 'Es wurden keine Probleme gefunden.', 'No project type has been created yet.' => 'Es wurden noch keine Projekttypen angelegt.', + 'No quotations or orders have been created yet.' => '', 'No report with id #1' => 'Es gibt keinen Report mit der Id #1', 'No requirement spec statuses has been created yet.' => 'Es wurden noch keine Pflichtenheftstatus angelegt.', 'No requirement spec templates have been created yet.' => 'Es wurden noch keine Pflichtenheftvorlangen angelegt.', @@ -1488,6 +1494,7 @@ $self->{texts} = { 'No risks level has been created yet.' => 'Es wurden noch keine Risikograde angelegt.', 'No sections created yet' => 'Keine Abschnitte erstellt', 'No sections have been created so far.' => 'Bisher wurden noch keine Abschnitte angelegt.', + 'No sections have been created yet.' => '', 'No shipto selected to delete' => 'Keine Lieferadresse zum Löschen ausgewählt', 'No summary account' => 'Kein Sammelkonto', 'No text blocks have been created for this position.' => 'Für diese Position wurden noch keine Textblöcke angelegt.', @@ -1574,6 +1581,7 @@ $self->{texts} = { 'Ordered' => 'Von Kunden bestellt', 'Orders' => 'Aufträge', 'Orders / Delivery Orders deleteable' => 'Aufträge / Lieferscheine löschbar', + 'Orders/Quotations actions' => '', 'Orientation' => 'Seitenformat', 'Orphaned' => 'Nie benutzt', 'Orphaned currencies' => 'Verwaiste Währungen', @@ -1807,6 +1815,7 @@ $self->{texts} = { 'Quotation Number missing!' => 'Angebotsnummer fehlt!', 'Quotation deleted!' => 'Angebot wurde gelöscht.', 'Quotations' => 'Angebote', + 'Quotations and orders' => '', 'Quote character' => 'Anführungszeichen-Symbol', 'Quote chararacter' => 'Anführungszeichen', 'Quoted' => 'Angeboten', @@ -1827,6 +1836,7 @@ $self->{texts} = { 'Reconciliation' => 'Kontenabgleich', 'Record Vendor Invoice' => 'Einkaufsrechnung erfassen', 'Record in' => 'Buchen auf', + 'Record number' => '', 'Recorded Tax' => 'Gespeicherte Steuern', 'Recorded taxkey' => 'Gespeicherter Steuerschlüssel', 'Reference' => 'Referenz', @@ -1875,6 +1885,7 @@ $self->{texts} = { 'Requirement Spec Templates' => 'Pflichtenheftvorlagen', 'Requirement Spec Type' => 'Pflichtenhefttyp', 'Requirement Spec Types' => 'Pflichtenhefttypen', + 'Requirement Spec Version' => '', 'Requirement Specs' => 'Pflichtenhefte', 'Requirement spec actions' => 'Pflichtenheftaktionen', 'Requirement spec function block #1 with #2 sub function blocks; description: "#3"' => 'Pflichtenheft-Funktionsblock #1 mit #2 Unterfunktionsblöcken; Beschreibung: "#3"', @@ -1932,6 +1943,7 @@ $self->{texts} = { 'Sales margin' => 'Marge', 'Sales margin %' => 'Marge prozentual', 'Sales net amount' => 'VK-Betrag', + 'Sales order' => '', 'Sales price' => 'VK-Preis', 'Sales price total' => 'VK-Betrag', 'Sales quotation' => 'Angebot', @@ -2537,6 +2549,7 @@ $self->{texts} = { 'Transaction' => 'Buchung', 'Transaction %d cancelled.' => 'Buchung %d erfolgreich storniert.', 'Transaction Date missing!' => 'Buchungsdatum fehlt!', + 'Transaction Description' => '', 'Transaction ID missing.' => 'Die Buchungs-ID fehlt.', 'Transaction deleted!' => 'Buchung gelöscht!', 'Transaction description' => 'Vorgangsbezeichnung', @@ -2602,6 +2615,7 @@ $self->{texts} = { 'Update prices' => 'Preise aktualisieren', 'Update prices of existing entries' => 'Preise von vorhandenen Artikeln aktualisieren', 'Update properties of existing entries' => 'Eigenschaften von existierenden Einträgen aktualisieren', + 'Update quotation/order' => '', 'Updated' => 'Erneuert am', 'Updating existing entry in database' => 'Existierenden Eintrag in Datenbank aktualisieren', 'Updating prices of existing entry in database' => 'Preis des Eintrags in der Datenbank wird aktualisiert', @@ -2868,6 +2882,7 @@ $self->{texts} = { 'new Window' => 'neues Fenster', 'next' => 'vor', 'no' => 'nein', + 'no article assigned yet' => '', 'no bestbefore' => 'keine Mindesthaltbarkeit', 'no chargenumber' => 'keine Chargennummer', 'none (pricegroup)' => 'keine', @@ -2965,6 +2980,7 @@ $self->{texts} = { 'vendor_list' => 'lieferantenliste', 'warehouse_journal_list' => 'lagerbuchungsliste', 'warehouse_report_list' => 'lagerbestandsliste', + 'working copy' => '', 'wrongformat' => 'Falsches Format', 'yearly' => 'jährlich', 'yes' => 'ja', diff --git a/templates/webpages/requirement_spec/show.html b/templates/webpages/requirement_spec/show.html index 072c6255a..f5321180f 100644 --- a/templates/webpages/requirement_spec/show.html +++ b/templates/webpages/requirement_spec/show.html @@ -13,6 +13,7 @@
  • [%- LxERP.t8("Time and cost estimate") %]
  • [%- UNLESS SELF.requirement_spec.is_template %]
  • [%- LxERP.t8("Versions") %]
  • +
  • [%- LxERP.t8("Quotations and orders") %]
  • [%- END %] diff --git a/templates/webpages/requirement_spec_order/list.html b/templates/webpages/requirement_spec_order/list.html new file mode 100644 index 000000000..fb86baf5c --- /dev/null +++ b/templates/webpages/requirement_spec_order/list.html @@ -0,0 +1,77 @@ +[%- USE HTML -%][%- USE LxERP -%][%- USE L -%][%- USE P -%] +
    +

    [% LxERP.t8("Assignment of articles to sections") %]

    + [% SET sections = SELF.requirement_spec.sections_sorted %] + [% IF !sections.size %] +
    + [% LxERP.t8("No sections have been created yet.") %] +
    + [% ELSE %] + + + + + + + + + + + + [% FOREACH section = sections %] + + + + + + + [% END %] + +
    [% LxERP.t8("Number") %][% LxERP.t8("Title") %][% LxERP.t8("Description") %][% LxERP.t8("Article") %]
    [% HTML.escape(section.fb_number) %][% HTML.escape(section.title) %][% HTML.escape(P.truncate(section.description)) %] + [% IF section.order_part %] + [% HTML.escape(section.order_part.partnumber) %] [% HTML.escape(section.order_part.description) %] + [% ELSE %] + [% LxERP.t8("no article assigned yet") %] + [% END %] +
    + [% END %] + +

    [% LxERP.t8("Quotations and orders") %]

    + + [% SET orders = SELF.requirement_spec.orders_sorted %] + [% IF !orders.size %] +
    [% LxERP.t8("No quotations or orders have been created yet.") %]
    + [% ELSE %] + + + + + + + + + + + + + + [% FOREACH rs_order = orders %] + + [% L.hidden_tag('order_id', rs_order.id, no_id=1) %] + + + + + + + [%- END %] + +
    [% LxERP.t8("Type") %][% LxERP.t8("Requirement Spec Version") %][% LxERP.t8("Record number") %][% LxERP.t8("Transaction Description") %][% LxERP.t8("Date") %]
    [% rs_order.order.type == 'sales_quotation' ? LxERP.t8('Sales quotation') : LxERP.t8('Sales order') %] + [% IF rs_order.version %] + [% HTML.escape(rs_order.version.version_number) %] + [% ELSE %] + [% LxERP.t8("working copy") %] + [% END %] + [% HTML.escape(rs_order.order.quotation ? rs_order.order.quonumber : rs_order.order.ordnumber) %][% HTML.escape(rs_order.order.transaction_description) %][% rs_order.itime.to_kivitendo(precision='day') %]
    + [% END %] +
    -- 2.20.1