1 package FS::part_export::batch_Common;
4 use base 'FS::part_export';
5 use FS::Record qw(qsearch qsearchs);
7 use FS::export_batch_item;
8 use Storable qw(nfreeze thaw);
9 use MIME::Base64 qw(encode_base64 decode_base64);
13 FS::part_export::batch_Common should be inherited by any export that stores
14 pending service changes and processes them all at once. It provides the
15 external interface, and has an internal interface that the subclass must
20 ACTION in all of these methods is one of 'insert', 'delete', 'replace',
21 'suspend', 'unsuspend', 'pkg_change', or 'relocate'.
23 ARGUMENTS is the arguments to the export_* method:
25 - for insert, the new service
27 - for suspend, unsuspend, or delete, the service to act on
29 - for replace, the new service, followed by the old service
31 - for pkg_change, the service, followed by the new and old packages
32 (as L<FS::cust_pkg> objects)
34 - for relocate, the service, followed by the new location and old location
35 (as L<FS::cust_location> objects)
39 =item immediate ACTION, ARGUMENTS
41 This is called immediately from the export_* method, and does anything
42 that needs to happen right then, except for inserting the
43 L<FS::export_batch_item> record. Optional. If it exists, it can return
44 a non-empty error string to cause the export to fail.
46 =item data ACTION, ARGUMENTS
48 This is called just before inserting the batch item, and returns a scalar
49 to store in the item's C<data> field. If the export needs to remember
50 anything about the service for the later batch-processing stage, it goes
51 here. Remember that if the service is being deleted, the export will need
52 to remember enough information to unprovision it when it's no longer in the
55 If this returns a reference, it will be frozen down with Base64-Storable.
59 This is called from freeside-daily, once for each batch still in the 'open'
60 or 'closed' state. It's expected to do whatever needs to be done with the
61 batch, and report failure via die().
75 $self->immediate('insert', $svc) || $self->create_item('insert', $svc);
82 $self->immediate('delete', $svc) || $self->create_item('delete', $svc);
89 $self->immediate('suspend', $svc) || $self->create_item('suspend', $svc);
92 sub export_unsuspend {
96 $self->immediate('unsuspend', $svc) || $self->create_item('unsuspend', $svc);
104 $self->immediate('replace', $new, $old)
105 || $self->create_item('replace', $new, $old)
108 sub export_relocate {
114 $self->immediate('relocate', $svc, $new_loc, $old_loc)
115 || $self->create_item('relocate', $svc, $new_loc, $old_loc)
118 sub export_pkg_change {
124 $self->immediate('pkg_change', $svc, $new_pkg)
125 || $self->create_item('pkg_change', $svc, $new_pkg)
128 =item create_item ACTION, ARGUMENTS
130 Creates and inserts the L<FS::export_batch_item> record for the action.
140 my $data = $self->data($action, $svc, @_);
143 $data = base64_encode(nfreeze($data));
146 my $batch_item = FS::export_batch_item->new({
147 'svcnum' => $svc->svcnum,
152 return $self->add_to_batch($batch_item);
155 sub immediate { # stub
159 =item add_to_batch ITEM
161 Actually inserts ITEM into the appropriate open batch. All fields in ITEM
162 will be populated except for 'batchnum'. By default, all items for a
163 single export will go into the same batch, but subclass exports may override
170 my $batch_item = shift;
171 $batch_item->set( 'batchnum', $self->open_batch->batchnum );
178 Returns the current open batch for this export. If there isn't one yet,
179 this will create one.
185 my $batch = qsearchs('export_batch', { status => 'open',
186 exportnum => $self->exportnum });
188 $batch = FS::export_batch->new({
190 exportnum => $self->exportnum
192 my $error = $batch->insert;
193 die $error if $error;